From babf81ea314cb82e6e5636908f998959673f7351 Mon Sep 17 00:00:00 2001 From: BWS Systems Date: Wed, 1 Feb 2017 11:36:51 -0600 Subject: [PATCH 01/13] Update Version --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index a33b794..e0c06d8 100644 --- a/README.md +++ b/README.md @@ -33,23 +33,23 @@ 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-4.1.1.jar +java -jar ha-bridge-4.1.2.jar ``` ### Automation on Linux systems To have this configured and running automatically there are a few resources to use. One is using Docker and a docker container has been built for this and can be gotten here: https://github.com/aptalca/docker-ha-bridge -Create the directory and make sure that ha-bridge-4.1.1.jar is in your /home/pi/habridge directory. +Create the directory and make sure that ha-bridge-4.1.2.jar is in your /home/pi/habridge directory. ``` pi@raspberrypi:~ $ mkdir habridge pi@raspberrypi:~ $ cd habridge -pi@raspberrypi:~/habridge $ wget https://github.com/bwssytems/ha-bridge/releases/download/v4.1.1/ha-bridge-4.1.1.jar +pi@raspberrypi:~/habridge $ wget https://github.com/bwssytems/ha-bridge/releases/download/v4.1.2/ha-bridge-4.1.2.jar ``` -Create the directory and make sure that ha-bridge-4.1.1.jar is in your /home/pi/habridge directory. +Create the directory and make sure that ha-bridge-4.1.2.jar is in your /home/pi/habridge directory. ``` pi@raspberrypi:~ $ mkdir habridge pi@raspberrypi:~ $ cd habridge -pi@raspberrypi:~/habridge $ wget https://github.com/bwssytems/ha-bridge/releases/download/v4.1.1/ha-bridge-4.1.1.jar +pi@raspberrypi:~/habridge $ wget https://github.com/bwssytems/ha-bridge/releases/download/v4.1.2/ha-bridge-4.1.2.jar ``` #### System Control Setup on a pi (preferred) For next gen Linux systems (this includes the Raspberry Pi), here is a systemctl unit file that you can install. Here is a link on how to do this: https://www.digitalocean.com/community/tutorials/how-to-use-systemctl-to-manage-systemd-services-and-units @@ -69,7 +69,7 @@ After=network.target [Service] Type=simple -ExecStart=/usr/bin/java -jar -Dconfig.file=/home/pi/habridge/data/habridge.config /home/pi/habridge/ha-bridge-4.1.1.jar +ExecStart=/usr/bin/java -jar -Dconfig.file=/home/pi/habridge/data/habridge.config /home/pi/habridge/ha-bridge-4.1.2.jar [Install] WantedBy=multi-user.target @@ -104,7 +104,7 @@ Then cut and past this, modify any locations that are not correct ``` cd /home/pi/habridge rm /home/pi/habridge/habridge-log.txt -nohup java -jar -Dconfig.file=/home/pi/habridge/data/habridge.config /home/pi/habridge/ha-bridge-4.1.1.jar > /home/pi/habridge/habridge-log.txt 2>&1 & +nohup java -jar -Dconfig.file=/home/pi/habridge/data/habridge.config /home/pi/habridge/ha-bridge-4.1.2.jar > /home/pi/habridge/habridge-log.txt 2>&1 & chmod 777 /home/pi/habridge/habridge-log.txt ``` From 16a248ba8e9c7753cd1e612fb347655617c3da10 Mon Sep 17 00:00:00 2001 From: Admin Date: Wed, 1 Feb 2017 16:53:08 -0600 Subject: [PATCH 02/13] Starting impl of LIFX devices --- pom.xml | 7 +- .../bwssystems/HABridge/BridgeSettings.java | 1 + .../HABridge/BridgeSettingsDescriptor.java | 10 + .../bwssystems/HABridge/DeviceMapTypes.java | 2 + .../com/bwssystems/HABridge/HomeManager.java | 9 +- .../bwssystems/HABridge/hue/HueMulator.java | 1 - .../HABridge/plugins/lifx/LifxDevice.java | 47 +++++ .../HABridge/plugins/lifx/LifxEntry.java | 18 ++ .../HABridge/plugins/lifx/LifxHome.java | 177 ++++++++++++++++++ src/main/resources/public/scripts/app.js | 155 ++++++++++++++- src/main/resources/public/views/system.html | 6 + 11 files changed, 428 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/bwssystems/HABridge/plugins/lifx/LifxDevice.java create mode 100644 src/main/java/com/bwssystems/HABridge/plugins/lifx/LifxEntry.java create mode 100644 src/main/java/com/bwssystems/HABridge/plugins/lifx/LifxHome.java diff --git a/pom.xml b/pom.xml index 72d092f..077a0c8 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.bwssystems.HABridge ha-bridge - 4.1.2 + 4.1.2a jar HA Bridge @@ -121,6 +121,11 @@ junit 4.11 + + com.github.bwssytems + lifx-sdk-java + 2.1.1 + diff --git a/src/main/java/com/bwssystems/HABridge/BridgeSettings.java b/src/main/java/com/bwssystems/HABridge/BridgeSettings.java index 1d67a37..13d84d4 100644 --- a/src/main/java/com/bwssystems/HABridge/BridgeSettings.java +++ b/src/main/java/com/bwssystems/HABridge/BridgeSettings.java @@ -148,6 +148,7 @@ public class BridgeSettings extends BackupHandler { theBridgeSettings.setMqttconfigured(theBridgeSettings.isValidMQTT()); theBridgeSettings.setHassconfigured(theBridgeSettings.isValidHass()); theBridgeSettings.setDomoticzconfigured(theBridgeSettings.isValidDomoticz()); + // Lifx is either configured or not, so it does not need an update. if(serverPortOverride != null) theBridgeSettings.setServerPort(serverPortOverride); if(serverIpOverride != null) diff --git a/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java b/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java index 442513b..556d85f 100644 --- a/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java +++ b/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java @@ -40,6 +40,7 @@ public class BridgeSettingsDescriptor { private String hubversion; private IpList domoticzaddress; private boolean domoticzconfigured; + private boolean lifxconfigured; public BridgeSettingsDescriptor() { super(); @@ -263,6 +264,12 @@ public class BridgeSettingsDescriptor { public void setDomoticzconfigured(boolean domoticzconfigured) { this.domoticzconfigured = domoticzconfigured; } + public boolean isLifxconfigured() { + return lifxconfigured; + } + public void setLifxconfigured(boolean lifxconfigured) { + this.lifxconfigured = lifxconfigured; + } public Boolean isValidVera() { if(this.getVeraAddress() == null || this.getVeraAddress().getDevices().size() <= 0) return false; @@ -328,4 +335,7 @@ public class BridgeSettingsDescriptor { return false; return true; } + public Boolean isValidLifx() { + return this.isLifxconfigured(); + } } diff --git a/src/main/java/com/bwssystems/HABridge/DeviceMapTypes.java b/src/main/java/com/bwssystems/HABridge/DeviceMapTypes.java index 870fa2c..1ee8125 100644 --- a/src/main/java/com/bwssystems/HABridge/DeviceMapTypes.java +++ b/src/main/java/com/bwssystems/HABridge/DeviceMapTypes.java @@ -26,6 +26,7 @@ public class DeviceMapTypes { public final static String[] UDP_DEVICE_COMPAT = { "UDP", "UDP Device"}; public final static String[] HTTP_DEVICE = { "httpDevice", "HTTP Device"}; public final static String[] DOMOTICZ_DEVICE = { "domoticzDevice", "Domoticz Device"}; + public final static String[] LIFX_DEVICE = { "lifxDevice", "LIFX Device"}; public final static int typeIndex = 0; public final static int displayIndex = 1; @@ -46,6 +47,7 @@ public class DeviceMapTypes { deviceMapTypes.add(HASS_DEVICE); deviceMapTypes.add(HTTP_DEVICE); deviceMapTypes.add(HUE_DEVICE); + deviceMapTypes.add(LIFX_DEVICE); deviceMapTypes.add(MQTT_MESSAGE); deviceMapTypes.add(NEST_HOMEAWAY); deviceMapTypes.add(NEST_THERMO_SET); diff --git a/src/main/java/com/bwssystems/HABridge/HomeManager.java b/src/main/java/com/bwssystems/HABridge/HomeManager.java index 83b1118..ed51668 100644 --- a/src/main/java/com/bwssystems/HABridge/HomeManager.java +++ b/src/main/java/com/bwssystems/HABridge/HomeManager.java @@ -12,6 +12,7 @@ import com.bwssystems.HABridge.plugins.harmony.HarmonyHome; import com.bwssystems.HABridge.plugins.hass.HassHome; 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.mqtt.MQTTHome; import com.bwssystems.HABridge.plugins.tcp.TCPHome; import com.bwssystems.HABridge.plugins.udp.UDPHome; @@ -79,13 +80,17 @@ public class HomeManager { aHome = new UDPHome(bridgeSettings, aUdpDatagramSender); homeList.put(DeviceMapTypes.UDP_DEVICE[DeviceMapTypes.typeIndex], aHome); homeList.put(DeviceMapTypes.UDP_DEVICE_COMPAT[DeviceMapTypes.typeIndex], aHome); - + // Setup Vera Home if available aHome = new VeraHome(bridgeSettings); resourceList.put(DeviceMapTypes.VERA_DEVICE[DeviceMapTypes.typeIndex], aHome); resourceList.put(DeviceMapTypes.VERA_SCENE[DeviceMapTypes.typeIndex], aHome); - //setup the HomeAssistant configuration if available + //setup the Domoticz configuration if available aHome = new DomoticzHome(bridgeSettings); resourceList.put(DeviceMapTypes.DOMOTICZ_DEVICE[DeviceMapTypes.typeIndex], aHome); + //setup the Lifx configuration if available + aHome = new LifxHome(bridgeSettings); + resourceList.put(DeviceMapTypes.LIFX_DEVICE[DeviceMapTypes.typeIndex], aHome); + homeList.put(DeviceMapTypes.LIFX_DEVICE[DeviceMapTypes.typeIndex], aHome); } public Home findHome(String type) { diff --git a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java index 67b3db5..017d8e2 100644 --- a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java +++ b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java @@ -16,7 +16,6 @@ import com.bwssystems.HABridge.api.hue.HuePublicConfig; import com.bwssystems.HABridge.api.hue.StateChangeBody; import com.bwssystems.HABridge.api.hue.WhitelistEntry; import com.bwssystems.HABridge.dao.*; -import com.bwssystems.HABridge.plugins.hue.HueDeviceIdentifier; import com.bwssystems.HABridge.plugins.hue.HueHome; import com.bwssystems.HABridge.util.JsonTransformer; import com.google.gson.Gson; diff --git a/src/main/java/com/bwssystems/HABridge/plugins/lifx/LifxDevice.java b/src/main/java/com/bwssystems/HABridge/plugins/lifx/LifxDevice.java new file mode 100644 index 0000000..8ca81f9 --- /dev/null +++ b/src/main/java/com/bwssystems/HABridge/plugins/lifx/LifxDevice.java @@ -0,0 +1,47 @@ +package com.bwssystems.HABridge.plugins.lifx; + +import com.github.besherman.lifx.LFXGroup; +import com.github.besherman.lifx.LFXLight; + +public class LifxDevice { + private Object lifxObject; + private String type; + public final static String LIGHT_TYPE = "Light"; + public final static String GROUP_TYPE = "Group"; + + public LifxDevice(Object lifxObject, String type) { + super(); + this.lifxObject = lifxObject; + this.type = type; + } + + public LifxEntry toEntry() { + LifxEntry anEntry = null; + if(type.equals(LIGHT_TYPE)) { + anEntry = new LifxEntry(); + anEntry.setId(((LFXLight)lifxObject).getID()); + anEntry.setName(((LFXLight)lifxObject).getLabel()); + } + if(type.equals(GROUP_TYPE)) { + anEntry = new LifxEntry(); + anEntry.setId("na"); + anEntry.setName(((LFXGroup)lifxObject).getLabel()); + } + return anEntry; + } + public Object getLifxObject() { + return lifxObject; + } + + public void setLifxObject(Object lifxObject) { + this.lifxObject = lifxObject; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } +} \ No newline at end of file diff --git a/src/main/java/com/bwssystems/HABridge/plugins/lifx/LifxEntry.java b/src/main/java/com/bwssystems/HABridge/plugins/lifx/LifxEntry.java new file mode 100644 index 0000000..44574d5 --- /dev/null +++ b/src/main/java/com/bwssystems/HABridge/plugins/lifx/LifxEntry.java @@ -0,0 +1,18 @@ +package com.bwssystems.HABridge.plugins.lifx; + +public class LifxEntry { + private String name; + private String id; + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } +} diff --git a/src/main/java/com/bwssystems/HABridge/plugins/lifx/LifxHome.java b/src/main/java/com/bwssystems/HABridge/plugins/lifx/LifxHome.java new file mode 100644 index 0000000..1a03b88 --- /dev/null +++ b/src/main/java/com/bwssystems/HABridge/plugins/lifx/LifxHome.java @@ -0,0 +1,177 @@ +package com.bwssystems.HABridge.plugins.lifx; + +import java.io.IOException; +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.BridgeSettingsDescriptor; +import com.bwssystems.HABridge.Home; +import com.bwssystems.HABridge.api.CallItem; +import com.bwssystems.HABridge.dao.DeviceDescriptor; +import com.bwssystems.HABridge.hue.BrightnessDecode; +import com.bwssystems.HABridge.hue.MultiCommandUtil; +import com.github.besherman.lifx.LFXClient; +import com.github.besherman.lifx.LFXGroup; +import com.github.besherman.lifx.LFXGroupCollection; +import com.github.besherman.lifx.LFXLight; +import com.github.besherman.lifx.LFXLightCollection; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +public class LifxHome implements Home { + private static final Logger log = LoggerFactory.getLogger(LifxHome.class); + private Map lifxMap; + private LFXClient client = new LFXClient(); + private Boolean validLifx; + private Gson aGsonHandler; + + public LifxHome(BridgeSettingsDescriptor bridgeSettings) { + super(); + createHome(bridgeSettings); + } + + @Override + public Home createHome(BridgeSettingsDescriptor bridgeSettings) { + lifxMap = null; + aGsonHandler = null; + validLifx = bridgeSettings.isValidLifx(); + log.info("LifxDevice Home created." + (validLifx ? "" : " No LifxDevices configured.")); + if(validLifx) { + try { + log.info("Open Lifx client...."); + client.open(true); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + aGsonHandler = + new GsonBuilder() + .create(); + lifxMap = new HashMap(); + this.addLifxLights(client.getLights()); + this.addLifxGroups(client.getGroups()); + } + return this; + } + + public LifxDevice getLifxDevice(String aName) { + if(!validLifx) + return null; + LifxDevice aLifxDevice = null; + if(aName == null || aName.equals("")) { + log.debug("Cannot get LifxDevice for name as it is empty."); + } + else { + aLifxDevice = lifxMap.get(aName); + log.debug("Retrieved a LifxDevice for name: " + aName); + } + return aLifxDevice; + } + + @Override + public Object getItems(String type) { + log.debug("consolidating devices for lifx"); + if(!validLifx) + return null; + LifxEntry theResponse = null; + Iterator keys = lifxMap.keySet().iterator(); + List deviceList = new ArrayList(); + while(keys.hasNext()) { + String key = keys.next(); + theResponse = lifxMap.get(key).toEntry(); + if(theResponse != null) + deviceList.add(theResponse); + else { + log.warn("Cannot get LifxDevice with name: " + key + ", skipping this Lifx."); + continue; + } + } + return deviceList; + } + + private Boolean addLifxLights(LFXLightCollection theDeviceList) { + if(!validLifx) + return false; + Iterator devices = theDeviceList.iterator();; + while(devices.hasNext()) { + LFXLight theDevice = devices.next(); + LifxDevice aNewLifxDevice = new LifxDevice(theDevice, LifxDevice.LIGHT_TYPE); + lifxMap.put(aNewLifxDevice.toEntry().getName(), aNewLifxDevice); + } + return true; + } + + private Boolean addLifxGroups(LFXGroupCollection theDeviceList) { + if(!validLifx) + return false; + Iterator devices = theDeviceList.iterator();; + while(devices.hasNext()) { + LFXGroup theDevice = devices.next(); + LifxDevice aNewLifxDevice = new LifxDevice(theDevice, LifxDevice.GROUP_TYPE); + lifxMap.put(aNewLifxDevice.toEntry().getName(), aNewLifxDevice); + } + return true; + } + + @Override + public String deviceHandler(CallItem anItem, MultiCommandUtil aMultiUtil, String lightId, int intensity, + Integer targetBri, Integer targetBriInc, DeviceDescriptor device, String body) { + String theReturn = null; + log.debug("executing HUE api request to send message to LifxDevice: " + anItem.getItem().toString()); + if(!validLifx) { + 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\"}}]"; + + } else { + LifxEntry lifxCommand = null; + if(anItem.getItem().isJsonObject()) + lifxCommand = aGsonHandler.fromJson(anItem.getItem(), LifxEntry.class); + else + lifxCommand = aGsonHandler.fromJson(anItem.getItem().getAsString(), LifxEntry.class); + int aBriValue = BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc); + LifxDevice theDevice = getLifxDevice(lifxCommand.getName()); + if (theDevice == null) { + 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\"}}]"; + } else { + log.debug("calling LifxDevice: " + lifxCommand.getName()); + if(theDevice.getType().equals(LifxDevice.LIGHT_TYPE)) { + LFXLight theLight = (LFXLight)theDevice.getLifxObject(); + if(body.contains("true")) + theLight.setPower(true); + if(body.contains("false")) + theLight.setPower(false); + if(targetBri != null || targetBriInc != null) + theLight.setBrightness((float)(aBriValue/254)); + } else if (theDevice.getType().equals(LifxDevice.GROUP_TYPE)) { + LFXGroup theGroup = (LFXGroup)theDevice.getLifxObject(); + if(body.contains("true")) + theGroup.setPower(true); + if(body.contains("false")) + theGroup.setPower(false); + } + } + } + return theReturn; + } + + @Override + public void closeHome() { + if(!validLifx) + return; + client.close(); + } +} diff --git a/src/main/resources/public/scripts/app.js b/src/main/resources/public/scripts/app.js index e22505a..e6ae6d4 100644 --- a/src/main/resources/public/scripts/app.js +++ b/src/main/resources/public/scripts/app.js @@ -45,6 +45,9 @@ app.config (function ($locationProvider, $routeProvider) { }).when ('/domoticzdevices', { templateUrl: 'views/domoticzdevice.html', controller: 'DomoticzController' + }).when ('/lifxdevices', { + templateUrl: 'views/lifxdevice.html', + controller: 'DomoticzController' }).otherwise ({ templateUrl: 'views/configuration.html', controller: 'ViewingController' @@ -71,7 +74,7 @@ String.prototype.replaceAll = function (search, replace) app.service ('bridgeService', function ($http, $window, ngToast) { var self = this; - this.state = {base: window.location.origin + "/api/devices", bridgelocation: window.location.origin, systemsbase: window.location.origin + "/system", huebase: window.location.origin + "/api", configs: [], backups: [], devices: [], device: {}, mapandid: [], type: "", settings: [], myToastMsg: [], logMsgs: [], loggerInfo: [], mapTypes: [], olddevicename: "", logShowAll: false, isInControl: false, showVera: false, showHarmony: false, showNest: false, showHue: false, showHal: false, showMqtt: false, showHass: false, showDomoticz: false, habridgeversion: ""}; + this.state = {base: window.location.origin + "/api/devices", bridgelocation: window.location.origin, systemsbase: window.location.origin + "/system", huebase: window.location.origin + "/api", configs: [], backups: [], devices: [], device: {}, mapandid: [], type: "", settings: [], myToastMsg: [], logMsgs: [], loggerInfo: [], mapTypes: [], olddevicename: "", logShowAll: false, isInControl: false, showVera: false, showHarmony: false, showNest: false, showHue: false, showHal: false, showMqtt: false, showHass: false, showDomoticz: false, showLifx: false, habridgeversion: ""}; this.displayWarn = function(errorTitle, error) { var toastContent = errorTitle; @@ -257,6 +260,11 @@ app.service ('bridgeService', function ($http, $window, ngToast) { return; } + this.updateShowLifx = function () { + this.state.showDomoticz = self.state.settings.lifxconfigured; + return; + } + this.loadBridgeSettings = function () { return $http.get(this.state.systemsbase + "/settings").then( function (response) { @@ -450,6 +458,19 @@ app.service ('bridgeService', function ($http, $window, ngToast) { ); }; + 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) { + self.displayWarn("Get Lifx Devices Error: ", error); + } + ); + }; + this.formatCallItem = function (currentItem) { if(!currentItem.startsWith("{\"item") && !currentItem.startsWith("[{\"item")) { if (currentItem.startsWith("[") || currentItem.startsWith("{")) @@ -2295,6 +2316,124 @@ app.controller('DomoticzController', function ($scope, $location, $http, bridgeS }; }); +app.controller('LifxController', function ($scope, $location, $http, bridgeService, ngDialog) { + $scope.bridge = bridgeService.state; + $scope.device = bridgeService.state.device; + $scope.device_dim_control = ""; + $scope.bulk = { devices: [] }; + $scope.selectAll = false; + bridgeService.viewLifxDevices(); + $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; + $scope.buttonsVisible = false; + + $scope.clearDevice = function () { + bridgeService.clearDevice(); + $scope.device = bridgeService.state.device; + }; + + $scope.buildDeviceUrls = function (lifxdevice, dim_control) { + dimpayload = "{\"name\":\"" + lifxdevice.name + "\"}"; + onpayload = "{\"name\":\"" + lifxdevice.name + "\"}"; + offpayload = "{\"name\":\"" + lifxdevice.name + "\"}"; + bridgeService.buildUrls(onpayload, dimpayload, offpayload, false, lifxdevice.name, lifxdevice.name, lifxdevice.name, aDeviceType, "lifxDevice", null, null); + $scope.device = bridgeService.state.device; + bridgeService.editNewDevice($scope.device); + $location.path('/editdevice'); + }; + + $scope.bulkAddDevices = function(dim_control) { + var devicesList = []; + 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); + 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 + }; + } + } + } + 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: [] }; + $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.haldevices.length; x++) { + if($scope.bulk.devices.indexOf(bridgeService.state.haldevices[x]) < 0 && !bridgeService.findDeviceByMapId(bridgeService.state.haldevices[x].haldevicename + "-" + bridgeService.state.haldevices[x].halname, bridgeService.state.haldevices[x].halname, "halDevice")) + $scope.bulk.devices.push(bridgeService.state.haldevices[x].haldevicename); + } + } + }; + + $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, $http, bridgeService) { bridgeService.viewMapTypes(); $scope.bridge = bridgeService.state; @@ -2566,6 +2705,20 @@ app.filter('configuredDomoticzItems', function (bridgeService) { } }); +app.filter('configuredLifxItems', 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], "lifx")) { + out.push(input[i]); + } + } + return out; + } +}); + app.controller('VersionController', function ($scope, bridgeService) { $scope.bridge = bridgeService.state; }); \ 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 6451311..19564fb 100644 --- a/src/main/resources/public/views/system.html +++ b/src/main/resources/public/views/system.html @@ -375,6 +375,12 @@ ng-model="bridge.settings.farenheit" ng-true-value=true ng-false-value=false> {{bridge.settings.farenheit}} + + LIFX Support + {{bridge.settings.lifxconfigured}} + Emulate Hue Hub Version Date: Thu, 2 Feb 2017 11:00:50 -0600 Subject: [PATCH 03/13] Beta impl of LIFX complete --- pom.xml | 2 +- .../devicemanagmeent/DeviceResource.java | 6 + .../HABridge/plugins/lifx/LifxDevice.java | 2 + .../HABridge/plugins/lifx/LifxEntry.java | 7 + src/main/resources/public/scripts/app.js | 11 +- .../resources/public/views/configuration.html | 1 + .../public/views/domoticzdevice.html | 5 +- .../resources/public/views/editdevice.html | 3 +- .../resources/public/views/haldevice.html | 5 +- .../public/views/harmonyactivity.html | 1 + .../resources/public/views/harmonydevice.html | 1 + .../resources/public/views/hassdevice.html | 5 +- .../resources/public/views/huedevice.html | 5 +- .../resources/public/views/lifxdevice.html | 122 ++++++++++++++++++ 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 | 1 + .../resources/public/views/veradevice.html | 5 +- .../resources/public/views/verascene.html | 1 + 20 files changed, 169 insertions(+), 17 deletions(-) create mode 100644 src/main/resources/public/views/lifxdevice.html diff --git a/pom.xml b/pom.xml index 077a0c8..4e1ff3f 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.bwssystems.HABridge ha-bridge - 4.1.2a + 4.1.2b jar HA Bridge diff --git a/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java b/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java index e4b861b..98aaa63 100644 --- a/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java +++ b/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java @@ -219,6 +219,12 @@ public class DeviceResource { return homeManager.findResource(DeviceMapTypes.DOMOTICZ_DEVICE[DeviceMapTypes.typeIndex]).getItems(DeviceMapTypes.DOMOTICZ_DEVICE[DeviceMapTypes.typeIndex]); }, new JsonTransformer()); + get (API_CONTEXT + "/lifx/devices", "application/json", (request, response) -> { + log.debug("Get LIFX devices"); + response.status(HttpStatus.SC_OK); + return homeManager.findResource(DeviceMapTypes.LIFX_DEVICE[DeviceMapTypes.typeIndex]).getItems(DeviceMapTypes.LIFX_DEVICE[DeviceMapTypes.typeIndex]); + }, new JsonTransformer()); + get (API_CONTEXT + "/map/types", "application/json", (request, response) -> { log.debug("Get map types"); return new DeviceMapTypes().getDeviceMapTypes(); diff --git a/src/main/java/com/bwssystems/HABridge/plugins/lifx/LifxDevice.java b/src/main/java/com/bwssystems/HABridge/plugins/lifx/LifxDevice.java index 8ca81f9..ea99d9d 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/lifx/LifxDevice.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/lifx/LifxDevice.java @@ -21,11 +21,13 @@ public class LifxDevice { anEntry = new LifxEntry(); anEntry.setId(((LFXLight)lifxObject).getID()); anEntry.setName(((LFXLight)lifxObject).getLabel()); + anEntry.setType(LIGHT_TYPE); } if(type.equals(GROUP_TYPE)) { anEntry = new LifxEntry(); anEntry.setId("na"); anEntry.setName(((LFXGroup)lifxObject).getLabel()); + anEntry.setType(GROUP_TYPE); } return anEntry; } diff --git a/src/main/java/com/bwssystems/HABridge/plugins/lifx/LifxEntry.java b/src/main/java/com/bwssystems/HABridge/plugins/lifx/LifxEntry.java index 44574d5..831095d 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/lifx/LifxEntry.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/lifx/LifxEntry.java @@ -3,6 +3,7 @@ package com.bwssystems.HABridge.plugins.lifx; public class LifxEntry { private String name; private String id; + private String type; public String getName() { return name; } @@ -15,4 +16,10 @@ public class LifxEntry { public void setId(String id) { this.id = id; } + public String getType() { + return type; + } + public void setType(String type) { + this.type = type; + } } diff --git a/src/main/resources/public/scripts/app.js b/src/main/resources/public/scripts/app.js index e6ae6d4..5226dac 100644 --- a/src/main/resources/public/scripts/app.js +++ b/src/main/resources/public/scripts/app.js @@ -261,7 +261,7 @@ app.service ('bridgeService', function ($http, $window, ngToast) { } this.updateShowLifx = function () { - this.state.showDomoticz = self.state.settings.lifxconfigured; + this.state.showLifx = self.state.settings.lifxconfigured; return; } @@ -277,6 +277,7 @@ app.service ('bridgeService', function ($http, $window, ngToast) { self.updateShowMqtt(); self.updateShowHass(); self.updateShowDomoticz(); + self.updateShowLifx(); }, function (error) { self.displayWarn("Load Bridge Settings Error: ", error); @@ -2332,10 +2333,10 @@ app.controller('LifxController', function ($scope, $location, $http, bridgeServi }; $scope.buildDeviceUrls = function (lifxdevice, dim_control) { - dimpayload = "{\"name\":\"" + lifxdevice.name + "\"}"; - onpayload = "{\"name\":\"" + lifxdevice.name + "\"}"; - offpayload = "{\"name\":\"" + lifxdevice.name + "\"}"; - bridgeService.buildUrls(onpayload, dimpayload, offpayload, false, lifxdevice.name, lifxdevice.name, lifxdevice.name, aDeviceType, "lifxDevice", null, null); + dimpayload = angular.toJson(lifxdevice); + onpayload = angular.toJson(lifxdevice); + offpayload = angular.toJson(lifxdevice); + bridgeService.buildUrls(onpayload, dimpayload, offpayload, false, lifxdevice.name, lifxdevice.name, lifxdevice.name, null, "lifxDevice", null, null); $scope.device = bridgeService.state.device; bridgeService.editNewDevice($scope.device); $location.path('/editdevice'); diff --git a/src/main/resources/public/views/configuration.html b/src/main/resources/public/views/configuration.html index 07a9962..e24e642 100644 --- a/src/main/resources/public/views/configuration.html +++ b/src/main/resources/public/views/configuration.html @@ -20,6 +20,7 @@
  • MQTT Messages
  • HomeAssistant Devices
  • Domoticz Devices
  • +
  • LIFX Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/domoticzdevice.html b/src/main/resources/public/views/domoticzdevice.html index 100c418..2359739 100644 --- a/src/main/resources/public/views/domoticzdevice.html +++ b/src/main/resources/public/views/domoticzdevice.html @@ -18,6 +18,7 @@
  • MQTT Messages
  • HomeAssistant Devices
  • +
  • LIFX Devices
  • Add/Edit
  • @@ -35,7 +36,7 @@ done in the edit tab, click the 'Add Bridge Device' to finish that selection setup. The 'Already Configured Domoticz Devices' list below will show what is already setup for your Domoticz.

    -

    +

    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 +

    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 Domoticz.

    diff --git a/src/main/resources/public/views/editdevice.html b/src/main/resources/public/views/editdevice.html index 625a147..9a33a1c 100644 --- a/src/main/resources/public/views/editdevice.html +++ b/src/main/resources/public/views/editdevice.html @@ -20,6 +20,7 @@
  • HomeAssistant Devices
  • Domoticz Devices
  • +
  • LIFX Devices
  • @@ -43,7 +44,7 @@ (${intensity..byte},${intensity.percent},${intensity.math(X*1)}) will also work. Also, you can go back to any helper tab and click a build action button to add another item for a multi-command.

    -

    When copying, update the name and select the "Add Bridge +

    When copying, update the name and select the "Add Bridge Device" Button.

    diff --git a/src/main/resources/public/views/haldevice.html b/src/main/resources/public/views/haldevice.html index 31813ef..a185dbe 100644 --- a/src/main/resources/public/views/haldevice.html +++ b/src/main/resources/public/views/haldevice.html @@ -17,6 +17,7 @@
  • MQTT Messages
  • HomeAssistant Devices
  • Domoticz Devices
  • +
  • LIFX Devices
  • Add/Edit
  • @@ -34,7 +35,7 @@ done in the edit tab, click the 'Add Bridge Device' to finish that selection setup. The 'Already Configured HAL Devices' list below will show what is already setup for your HAL.

    -

    +

    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 +

    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 HAL.

    diff --git a/src/main/resources/public/views/harmonyactivity.html b/src/main/resources/public/views/harmonyactivity.html index f933b0b..a82a0c7 100644 --- a/src/main/resources/public/views/harmonyactivity.html +++ b/src/main/resources/public/views/harmonyactivity.html @@ -18,6 +18,7 @@
  • MQTT Messages
  • HomeAssistant Devices
  • Domoticz Devices
  • +
  • LIFX Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/harmonydevice.html b/src/main/resources/public/views/harmonydevice.html index 137df4d..6b01a15 100644 --- a/src/main/resources/public/views/harmonydevice.html +++ b/src/main/resources/public/views/harmonydevice.html @@ -18,6 +18,7 @@
  • MQTT Messages
  • HomeAssistant Devices
  • Domoticz Devices
  • +
  • LIFX Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/hassdevice.html b/src/main/resources/public/views/hassdevice.html index 5d6284e..71d9b19 100644 --- a/src/main/resources/public/views/hassdevice.html +++ b/src/main/resources/public/views/hassdevice.html @@ -18,6 +18,7 @@
  • MQTT Messages
  • Domoticz Devices
  • +
  • LIFX Devices
  • Add/Edit
  • @@ -35,7 +36,7 @@ done in the edit tab, click the 'Add Bridge Device' to finish that selection setup. The 'Already Configured HomeAssistant Devices' list below will show what is already setup for your HomeAssitant.

    -

    +

    Also, use this select menu for which type of dim control you would like to be generated, BUT for Home Assistant, the selection should be Pass-thru:

    -

    Use the check boxes by the names to use the bulk addition +

    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 HomeAssitant.

    diff --git a/src/main/resources/public/views/huedevice.html b/src/main/resources/public/views/huedevice.html index 36fa45d..e3ae20d 100644 --- a/src/main/resources/public/views/huedevice.html +++ b/src/main/resources/public/views/huedevice.html @@ -18,6 +18,7 @@
  • MQTT Messages
  • HomeAssistant Devices
  • Domoticz Devices
  • +
  • LIFX Devices
  • Add/Edit
  • @@ -35,9 +36,9 @@ done in the edit tab, click the 'Add Bridge Device' to finish that selection setup. The 'Already Configured Hue Devices' list below will show what is already setup for your Hue.

    -

    Use the check boxes by the names to use the bulk addition +

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

    diff --git a/src/main/resources/public/views/lifxdevice.html b/src/main/resources/public/views/lifxdevice.html new file mode 100644 index 0000000..3973984 --- /dev/null +++ b/src/main/resources/public/views/lifxdevice.html @@ -0,0 +1,122 @@ + + +
    +
    +

    LIFX Devices

    +
    +
    +

    For any LIFX 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 LIFX Devices' list below will show what + is already setup for your LIFX.

    + +

    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, off and dim + with the name of the device from the LIFX device.

    + +
    + + + + + + + + + + + + + + + + +
    Row + NameIDTypeBuild Actions
    {{$index+1}}{{lifxdev.name}}{{lifxdev.id}}{{lifxdev.type}} + +
    +
    + + + +
    +
    +

    + Already Configured LIFX Devices +

    +
    +
    + + + + + + + + + + + + + + + + + + +
    RowNameLight NameMap IdActions
    {{$index+1}}{{device.name}}{{device.targetDevice}}{{device.mapId}} +

    + + +

    +
    +
    +
    +
    + \ No newline at end of file diff --git a/src/main/resources/public/views/logs.html b/src/main/resources/public/views/logs.html index 3645df5..a1939e9 100644 --- a/src/main/resources/public/views/logs.html +++ b/src/main/resources/public/views/logs.html @@ -18,6 +18,7 @@
  • MQTT Messages
  • HomeAssistant Devices
  • Domoticz Devices
  • +
  • LIFX Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/mqttpublish.html b/src/main/resources/public/views/mqttpublish.html index 05f977b..6fd06db 100644 --- a/src/main/resources/public/views/mqttpublish.html +++ b/src/main/resources/public/views/mqttpublish.html @@ -12,6 +12,7 @@
  • HomeAssistant Devices
  • Domoticz Devices
  • +
  • LIFX Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/nestactions.html b/src/main/resources/public/views/nestactions.html index 574b84b..59cdfbe 100644 --- a/src/main/resources/public/views/nestactions.html +++ b/src/main/resources/public/views/nestactions.html @@ -18,6 +18,7 @@
  • MQTT Messages
  • HomeAssistant Devices
  • Domoticz Devices
  • +
  • LIFX Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/system.html b/src/main/resources/public/views/system.html index 19564fb..62e3bd8 100644 --- a/src/main/resources/public/views/system.html +++ b/src/main/resources/public/views/system.html @@ -19,6 +19,7 @@
  • MQTT Messages
  • HomeAssistant Devices
  • Domoticz Devices
  • +
  • LIFX Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/veradevice.html b/src/main/resources/public/views/veradevice.html index f1eeaec..cba365c 100644 --- a/src/main/resources/public/views/veradevice.html +++ b/src/main/resources/public/views/veradevice.html @@ -17,6 +17,7 @@
  • MQTT Messages
  • HomeAssistant Devices
  • Domoticz Devices
  • +
  • LIFX Devices
  • Add/Edit
  • @@ -35,7 +36,7 @@ done in the edit tab, click the 'Add Bridge Device' to finish that selection setup. The 'Already Configured Vera Devices' list below will show what is already setup for your Vera.

    -

    +

    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 +

    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 Vera.

    diff --git a/src/main/resources/public/views/verascene.html b/src/main/resources/public/views/verascene.html index 9e9f30c..70d8aba 100644 --- a/src/main/resources/public/views/verascene.html +++ b/src/main/resources/public/views/verascene.html @@ -17,6 +17,7 @@
  • MQTT Messages
  • HomeAssistant Devices
  • Domoticz Devices
  • +
  • LIFX Devices
  • Add/Edit
  • From 0ac8061118c04c6ccce8a29299239cb6fd505dea Mon Sep 17 00:00:00 2001 From: Admin Date: Fri, 3 Feb 2017 09:29:49 -0600 Subject: [PATCH 04/13] Updated LIFX impl --- pom.xml | 2 +- src/main/resources/public/scripts/app.js | 4 ++-- src/main/resources/public/views/lifxdevice.html | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 4e1ff3f..e45878c 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.bwssystems.HABridge ha-bridge - 4.1.2b + 4.1.2c jar HA Bridge diff --git a/src/main/resources/public/scripts/app.js b/src/main/resources/public/scripts/app.js index 5226dac..a6cf1b2 100644 --- a/src/main/resources/public/scripts/app.js +++ b/src/main/resources/public/scripts/app.js @@ -47,7 +47,7 @@ app.config (function ($locationProvider, $routeProvider) { controller: 'DomoticzController' }).when ('/lifxdevices', { templateUrl: 'views/lifxdevice.html', - controller: 'DomoticzController' + controller: 'LifxController' }).otherwise ({ templateUrl: 'views/configuration.html', controller: 'ViewingController' @@ -2336,7 +2336,7 @@ app.controller('LifxController', function ($scope, $location, $http, bridgeServi dimpayload = angular.toJson(lifxdevice); onpayload = angular.toJson(lifxdevice); offpayload = angular.toJson(lifxdevice); - bridgeService.buildUrls(onpayload, dimpayload, offpayload, false, lifxdevice.name, lifxdevice.name, lifxdevice.name, null, "lifxDevice", null, null); + bridgeService.buildUrls(onpayload, dimpayload, offpayload, true, lifxdevice.name, lifxdevice.name, lifxdevice.name, null, "lifxDevice", null, null); $scope.device = bridgeService.state.device; bridgeService.editNewDevice($scope.device); $location.path('/editdevice'); diff --git a/src/main/resources/public/views/lifxdevice.html b/src/main/resources/public/views/lifxdevice.html index 3973984..9383e3a 100644 --- a/src/main/resources/public/views/lifxdevice.html +++ b/src/main/resources/public/views/lifxdevice.html @@ -59,7 +59,7 @@ {{lifxdev.type}} From dd0032a5677704503471a72767c0fb49d786c999 Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 7 Feb 2017 15:50:21 -0600 Subject: [PATCH 05/13] updatre lifx --- pom.xml | 4 +- .../HABridge/plugins/lifx/LifxHome.java | 65 ++++++++++++++++--- src/main/resources/public/scripts/app.js | 2 +- .../resources/public/views/lifxdevice.html | 2 +- 4 files changed, 60 insertions(+), 13 deletions(-) diff --git a/pom.xml b/pom.xml index e45878c..d016a14 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.bwssystems.HABridge ha-bridge - 4.1.2c + 4.1.2e jar HA Bridge @@ -124,7 +124,7 @@ com.github.bwssytems lifx-sdk-java - 2.1.1 + 2.1.5 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 1a03b88..924f8de 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/lifx/LifxHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/lifx/LifxHome.java @@ -19,15 +19,17 @@ import com.bwssystems.HABridge.hue.MultiCommandUtil; import com.github.besherman.lifx.LFXClient; import com.github.besherman.lifx.LFXGroup; import com.github.besherman.lifx.LFXGroupCollection; +import com.github.besherman.lifx.LFXGroupCollectionListener; import com.github.besherman.lifx.LFXLight; import com.github.besherman.lifx.LFXLightCollection; +import com.github.besherman.lifx.LFXLightCollectionListener; import com.google.gson.Gson; import com.google.gson.GsonBuilder; public class LifxHome implements Home { private static final Logger log = LoggerFactory.getLogger(LifxHome.class); private Map lifxMap; - private LFXClient client = new LFXClient(); + private LFXClient client; private Boolean validLifx; private Gson aGsonHandler; @@ -45,20 +47,23 @@ public class LifxHome implements Home { if(validLifx) { try { log.info("Open Lifx client...."); - client.open(true); + lifxMap = new HashMap(); + client = new LFXClient(); + client.getLights().addLightCollectionListener(new MyLightListener(lifxMap)); + client.getGroups().addGroupCollectionListener(new MyGroupListener(lifxMap)); + client.open(false); } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.warn("Could not open LIFX, with IO Exception", e); + client = null; + return this; } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.warn("Could not open LIFX, with Interruprted Exception", e); + client = null; + return this; } aGsonHandler = new GsonBuilder() .create(); - lifxMap = new HashMap(); - this.addLifxLights(client.getLights()); - this.addLifxGroups(client.getGroups()); } return this; } @@ -174,4 +179,46 @@ public class LifxHome implements Home { return; client.close(); } + private static class MyLightListener implements LFXLightCollectionListener { + private static final Logger log = LoggerFactory.getLogger(MyLightListener.class); + private Map aLifxMap; + public MyLightListener(Map theMap) { + aLifxMap = theMap; + } + @Override + public void lightAdded(LFXLight light) { + log.debug("Light added, label: " + light.getLabel() + " and id: " + light.getID()); + LifxDevice aNewLifxDevice = new LifxDevice(light, LifxDevice.LIGHT_TYPE); + aLifxMap.put(aNewLifxDevice.toEntry().getName(), aNewLifxDevice); + } + + @Override + public void lightRemoved(LFXLight light) { + log.debug("Light removed, label: " + light.getLabel() + " and id: " + light.getID()); + aLifxMap.remove(light.getLabel()); + } + + + } + private static class MyGroupListener implements LFXGroupCollectionListener { + private static final Logger log = LoggerFactory.getLogger(MyLightListener.class); + private Map aLifxMap; + public MyGroupListener(Map theMap) { + aLifxMap = theMap; + } + + @Override + public void groupAdded(LFXGroup group) { + log.debug("Group: " + group.getLabel() + " added: " + group.size()); + LifxDevice aNewLifxDevice = new LifxDevice(group, LifxDevice.GROUP_TYPE); + aLifxMap.put(aNewLifxDevice.toEntry().getName(), aNewLifxDevice); + } + + @Override + public void groupRemoved(LFXGroup group) { + log.debug("Group: " + group.getLabel() + " removed"); + aLifxMap.remove(group.getLabel()); + } + + } } diff --git a/src/main/resources/public/scripts/app.js b/src/main/resources/public/scripts/app.js index a6cf1b2..9e0cbf6 100644 --- a/src/main/resources/public/scripts/app.js +++ b/src/main/resources/public/scripts/app.js @@ -2374,7 +2374,7 @@ app.controller('LifxController', function ($scope, $location, $http, bridgeServi bridgeService.viewHalDevices(); }, function (error) { - bridgeService.displayWarn("Error adding HAL devices in bulk.", error) + bridgeService.displayWarn("Error adding LIFX devices in bulk.", error) } ); $scope.bulk = { devices: [] }; diff --git a/src/main/resources/public/views/lifxdevice.html b/src/main/resources/public/views/lifxdevice.html index 9383e3a..6278cea 100644 --- a/src/main/resources/public/views/lifxdevice.html +++ b/src/main/resources/public/views/lifxdevice.html @@ -92,7 +92,7 @@ + ng-repeat="device in bridge.devices | configuredLifxItems | orderBy:predicate:reverse"> {{$index+1}} {{device.name}} {{device.targetDevice}} From 0305646b4fd4e32e41fa9b356e0e4875de89bb40 Mon Sep 17 00:00:00 2001 From: Admin Date: Wed, 8 Feb 2017 15:15:53 -0600 Subject: [PATCH 06/13] Updated LIFX connection for broadcast address and changed the item collection to be asynchronous with LIFX. --- .../HABridge/plugins/lifx/LifxHome.java | 32 ++++++++++++++++--- 1 file changed, 28 insertions(+), 4 deletions(-) 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 924f8de..d83d3ee 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/lifx/LifxHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/lifx/LifxHome.java @@ -1,6 +1,10 @@ package com.bwssystems.HABridge.plugins.lifx; import java.io.IOException; +import java.net.Inet4Address; +import java.net.InetAddress; +import java.net.InterfaceAddress; +import java.net.NetworkInterface; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -28,6 +32,7 @@ import com.google.gson.GsonBuilder; public class LifxHome implements Home { private static final Logger log = LoggerFactory.getLogger(LifxHome.class); + private static final float DIM_DIVISOR = (float)254.00; private Map lifxMap; private LFXClient client; private Boolean validLifx; @@ -47,8 +52,21 @@ public class LifxHome implements Home { if(validLifx) { try { log.info("Open Lifx client...."); + InetAddress configuredAddress = InetAddress.getByName(bridgeSettings.getUpnpConfigAddress()); + NetworkInterface networkInterface = NetworkInterface.getByInetAddress(configuredAddress); + InetAddress bcastInetAddr = null; + if (networkInterface != null) { + for (InterfaceAddress ifaceAddr : networkInterface.getInterfaceAddresses()) { + InetAddress addr = ifaceAddr.getAddress(); + if (addr instanceof Inet4Address) { + bcastInetAddr = ifaceAddr.getBroadcast(); + break; + } + } + } lifxMap = new HashMap(); - client = new LFXClient(); + log.info("Opening LFX Client with broadcast address: " + bcastInetAddr.getHostAddress()); + client = new LFXClient(bcastInetAddr.getHostAddress()); client.getLights().addLightCollectionListener(new MyLightListener(lifxMap)); client.getGroups().addGroupCollectionListener(new MyGroupListener(lifxMap)); client.open(false); @@ -131,6 +149,8 @@ public class LifxHome implements Home { public String deviceHandler(CallItem anItem, MultiCommandUtil aMultiUtil, String lightId, int intensity, Integer targetBri, Integer targetBriInc, DeviceDescriptor device, String body) { String theReturn = null; + float aBriValue; + float theValue; log.debug("executing HUE api request to send message to LifxDevice: " + anItem.getItem().toString()); if(!validLifx) { log.warn("Should not get here, no LifxDevice clients configured"); @@ -144,7 +164,6 @@ public class LifxHome implements Home { lifxCommand = aGsonHandler.fromJson(anItem.getItem(), LifxEntry.class); else lifxCommand = aGsonHandler.fromJson(anItem.getItem().getAsString(), LifxEntry.class); - int aBriValue = BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc); LifxDevice theDevice = getLifxDevice(lifxCommand.getName()); if (theDevice == null) { log.warn("Should not get here, no LifxDevices available"); @@ -159,8 +178,13 @@ public class LifxHome implements Home { theLight.setPower(true); if(body.contains("false")) theLight.setPower(false); - if(targetBri != null || targetBriInc != null) - theLight.setBrightness((float)(aBriValue/254)); + if(targetBri != null || targetBriInc != null) { + aBriValue = (float)BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc); + theValue = aBriValue/DIM_DIVISOR; + if(theValue > (float)1.0) + theValue = (float)0.99; + theLight.setBrightness(theValue); + } } else if (theDevice.getType().equals(LifxDevice.GROUP_TYPE)) { LFXGroup theGroup = (LFXGroup)theDevice.getLifxObject(); if(body.contains("true")) From 6116d3767558d020aad4f922d1dc87f70d416ba1 Mon Sep 17 00:00:00 2001 From: Admin Date: Thu, 9 Feb 2017 08:41:40 -0600 Subject: [PATCH 07/13] update version --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index d016a14..039648d 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.bwssystems.HABridge ha-bridge - 4.1.2e + 4.1.2f jar HA Bridge @@ -124,7 +124,7 @@ com.github.bwssytems lifx-sdk-java - 2.1.5 + 2.1.6 From 61156e98209bea8ae81a8f4fc960151b48712526 Mon Sep 17 00:00:00 2001 From: Admin Date: Thu, 16 Feb 2017 13:36:23 -0600 Subject: [PATCH 08/13] Updated edit screen field layout with bootstrap grid. Added error checking for HTTP handler. --- pom.xml | 2 +- .../HABridge/plugins/http/HTTPHandler.java | 12 ++++++-- .../resources/public/views/editdevice.html | 28 +++++++++++++++---- .../resources/public/views/hassdevice.html | 2 +- 4 files changed, 35 insertions(+), 9 deletions(-) diff --git a/pom.xml b/pom.xml index 039648d..9ee9ce6 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.bwssystems.HABridge ha-bridge - 4.1.2f + 4.1.2g jar HA Bridge 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 6cab6e0..245b729 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHandler.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHandler.java @@ -125,8 +125,16 @@ public class HTTPHandler { + e.getMessage(), e); } } - if (theContent == null) - theContent = ""; + } else { + log.warn("HTTP response code was not an expected successful response of between 200 - 299, the code was: " + response.getStatusLine()); + try { + EntityUtils.consume(response.getEntity()); // close out + // inputstream + // ignore + // content + } catch (Exception e) { + //noop + } } } catch (IOException e) { log.warn("Error calling out to HA gateway: IOException in log", e); diff --git a/src/main/resources/public/views/editdevice.html b/src/main/resources/public/views/editdevice.html index 9a33a1c..f380fdd 100644 --- a/src/main/resources/public/views/editdevice.html +++ b/src/main/resources/public/views/editdevice.html @@ -130,6 +130,7 @@ +
    @@ -140,19 +141,21 @@ + +
    - - - - -
    Type Target Item DelayHttp Headers Content Type Manage