diff --git a/README.md b/README.md
index 303b704..0ef7aef 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.4.jar
+java -jar ha-bridge-4.2.0.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.4.jar is in your /home/pi/habridge directory.
+Create the directory and make sure that ha-bridge-4.2.0.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.4/ha-bridge-4.1.4.jar
+pi@raspberrypi:~/habridge $ wget https://github.com/bwssytems/ha-bridge/releases/download/v4.2.0/ha-bridge-4.2.0.jar
```
-Create the directory and make sure that ha-bridge-4.1.4.jar is in your /home/pi/habridge directory.
+Create the directory and make sure that ha-bridge-4.2.0.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.4/ha-bridge-4.1.4.jar
+pi@raspberrypi:~/habridge $ wget https://github.com/bwssytems/ha-bridge/releases/download/v4.2.0/ha-bridge-4.2.0.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.4.jar
+ExecStart=/usr/bin/java -jar -Dconfig.file=/home/pi/habridge/data/habridge.config /home/pi/habridge/ha-bridge-4.2.0.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.4.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.2.0.jar > /home/pi/habridge/habridge-log.txt 2>&1 &
chmod 777 /home/pi/habridge/habridge-log.txt
```
diff --git a/pom.xml b/pom.xml
index 07c2ae6..b10f483 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
com.bwssystems.HABridge
ha-bridge
- 4.1.4
+ 4.2.0
jar
HA Bridge
@@ -121,6 +121,11 @@
junit
4.11
+
+ com.github.bwssytems
+ lifx-sdk-java
+ 2.1.6
+
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 a328dc5..b11c76a 100644
--- a/src/main/java/com/bwssystems/HABridge/HomeManager.java
+++ b/src/main/java/com/bwssystems/HABridge/HomeManager.java
@@ -13,6 +13,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;
@@ -71,7 +72,6 @@ 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);
@@ -80,13 +80,18 @@ 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);
+ homeList.put(DeviceMapTypes.DOMOTICZ_DEVICE[DeviceMapTypes.typeIndex], aHome);
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/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/hue/BrightnessDecode.java b/src/main/java/com/bwssystems/HABridge/hue/BrightnessDecode.java
index 55da9dd..7c31f11 100644
--- a/src/main/java/com/bwssystems/HABridge/hue/BrightnessDecode.java
+++ b/src/main/java/com/bwssystems/HABridge/hue/BrightnessDecode.java
@@ -1,15 +1,10 @@
package com.bwssystems.HABridge.hue;
import java.math.BigDecimal;
-import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;
-
-import javax.xml.bind.DatatypeConverter;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
import net.java.dev.eval.Expression;
public class BrightnessDecode {
@@ -49,9 +44,7 @@ public class BrightnessDecode {
}
if (request.contains(INTENSITY_BYTE)) {
if (isHex) {
- BigInteger bigInt = BigInteger.valueOf(intensity);
- byte[] theBytes = bigInt.toByteArray();
- String hexValue = DatatypeConverter.printHexBinary(theBytes);
+ String hexValue = Integer.toHexString(intensity);
request = request.replace(INTENSITY_BYTE, hexValue);
} else {
String intensityByte = String.valueOf(intensity);
@@ -60,9 +53,7 @@ public class BrightnessDecode {
} else if (request.contains(INTENSITY_PERCENT)) {
int percentBrightness = (int) Math.round(intensity / 255.0 * 100);
if (isHex) {
- BigInteger bigInt = BigInteger.valueOf(percentBrightness);
- byte[] theBytes = bigInt.toByteArray();
- String hexValue = DatatypeConverter.printHexBinary(theBytes);
+ String hexValue = Integer.toHexString(percentBrightness);
request = request.replace(INTENSITY_PERCENT, hexValue);
} else {
String intensityPercent = String.valueOf(percentBrightness);
@@ -81,9 +72,7 @@ public class BrightnessDecode {
BigDecimal result = exp.eval(variables);
Integer endResult = Math.round(result.floatValue());
if (isHex) {
- BigInteger bigInt = BigInteger.valueOf(endResult);
- byte[] theBytes = bigInt.toByteArray();
- String hexValue = DatatypeConverter.printHexBinary(theBytes);
+ String hexValue = Integer.toHexString(endResult);
request = request.replace(INTENSITY_MATH + mathDescriptor + INTENSITY_MATH_CLOSE, hexValue);
} else {
request = request.replace(INTENSITY_MATH + mathDescriptor + INTENSITY_MATH_CLOSE,
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/domoticz/DomoticzHandler.java b/src/main/java/com/bwssystems/HABridge/plugins/domoticz/DomoticzHandler.java
index 379c7b7..56ada5a 100644
--- a/src/main/java/com/bwssystems/HABridge/plugins/domoticz/DomoticzHandler.java
+++ b/src/main/java/com/bwssystems/HABridge/plugins/domoticz/DomoticzHandler.java
@@ -3,11 +3,12 @@ package com.bwssystems.HABridge.plugins.domoticz;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
-
+import java.util.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.bwssystems.HABridge.NamedIP;
+import com.bwssystems.HABridge.api.NameValue;
import com.bwssystems.HABridge.plugins.http.HTTPHandler;
import com.google.gson.Gson;
@@ -16,32 +17,33 @@ public class DomoticzHandler {
private static final String GET_REQUEST = "/json.htm?type=";
private static final String DEVICES_TYPE = "devices";
private static final String SCENES_TYPE = "scenes";
- private static final String FILTER_USED = "&used=";
- private HTTPHandler httpClient;
+ private static final String FILTER_USED = "&used=true";
private NamedIP domoticzAddress;
public DomoticzHandler(NamedIP addressName) {
super();
- httpClient = new HTTPHandler();
domoticzAddress = addressName;
}
- public List getDevices() {
- return getDomoticzDevices(GET_REQUEST, DEVICES_TYPE, FILTER_USED);
+ public List getDevices(HTTPHandler httpClient) {
+ return getDomoticzDevices(GET_REQUEST, DEVICES_TYPE, FILTER_USED, httpClient);
}
- public List getScenes() {
- return getDomoticzDevices(GET_REQUEST, SCENES_TYPE, null);
+ public List getScenes(HTTPHandler httpClient) {
+ return getDomoticzDevices(GET_REQUEST, SCENES_TYPE, null, httpClient);
}
- private List getDomoticzDevices(String rootRequest, String type, String postpend) {
+ private List getDomoticzDevices(String rootRequest, String type, String postpend, HTTPHandler httpClient) {
Devices theDomoticzApiResponse = null;
List deviceList = null;
String theUrl = null;
String theData;
- theUrl = "http://" + domoticzAddress.getIp() + ":" + domoticzAddress.getPort() + rootRequest + type;
- theData = httpClient.doHttpRequest(theUrl, null, null, null, null);
+ if(postpend != null && !postpend.isEmpty())
+ theUrl = buildUrl(rootRequest + type + postpend);
+ else
+ theUrl = buildUrl(rootRequest + type);
+ theData = httpClient.doHttpRequest(theUrl, null, null, null, buildHeaders());
if(theData != null) {
log.debug("GET " + type + " DomoticzApiResponse - data: " + theData);
theDomoticzApiResponse = new Gson().fromJson(theData, Devices.class);
@@ -70,6 +72,44 @@ public class DomoticzHandler {
return deviceList;
}
+ public String buildUrl(String thePayload) {
+ String newUrl = null;
+
+ if(thePayload != null && !thePayload.isEmpty()) {
+ if(domoticzAddress.getSecure() != null && domoticzAddress.getSecure())
+ newUrl = "https://";
+ else
+ newUrl = "http://";
+
+ newUrl = newUrl + domoticzAddress.getIp();
+
+ if(domoticzAddress.getPort() != null && !domoticzAddress.getPort().isEmpty())
+ newUrl = newUrl + ":" + domoticzAddress.getPort();
+
+ if(thePayload.startsWith("/"))
+ newUrl = newUrl + thePayload;
+ else
+ newUrl = newUrl + "/" + thePayload;
+ }
+
+ return newUrl;
+ }
+
+ public NameValue[] buildHeaders() {
+ NameValue[] headers = null;
+
+ if(domoticzAddress.getUsername() != null && !domoticzAddress.getUsername().isEmpty()
+ && domoticzAddress.getPassword() != null && !domoticzAddress.getPassword().isEmpty()) {
+ NameValue theAuth = new NameValue();
+ theAuth.setName("Authorization");
+ String encoding = Base64.getEncoder().encodeToString((domoticzAddress.getUsername() + ":" + domoticzAddress.getPassword()).getBytes());
+ theAuth.setValue("Basic " + encoding);
+ headers = new NameValue[1];
+ headers[0] = theAuth;
+ }
+
+ return headers;
+ }
public NamedIP getDomoticzAddress() {
return domoticzAddress;
}
diff --git a/src/main/java/com/bwssystems/HABridge/plugins/domoticz/DomoticzHome.java b/src/main/java/com/bwssystems/HABridge/plugins/domoticz/DomoticzHome.java
index ebc5af8..e03b40a 100644
--- a/src/main/java/com/bwssystems/HABridge/plugins/domoticz/DomoticzHome.java
+++ b/src/main/java/com/bwssystems/HABridge/plugins/domoticz/DomoticzHome.java
@@ -13,13 +13,19 @@ 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.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 httpClient;
public DomoticzHome(BridgeSettingsDescriptor bridgeSettings) {
super();
@@ -36,14 +42,14 @@ public class DomoticzHome implements Home {
List deviceList = new ArrayList();
while(keys.hasNext()) {
String key = keys.next();
- theResponse = domoticzs.get(key).getDevices();
+ theResponse = domoticzs.get(key).getDevices(httpClient);
if(theResponse != null)
addDomoticzDevices(deviceList, theResponse, key);
else {
log.warn("Cannot get lights for Domoticz with name: " + key + ", skipping this Domoticz.");
continue;
}
- theResponse = domoticzs.get(key).getScenes();
+ theResponse = domoticzs.get(key).getScenes(httpClient);
if(theResponse != null)
addDomoticzDevices(deviceList, theResponse, key);
else
@@ -66,8 +72,54 @@ public class DomoticzHome implements Home {
@Override
public String deviceHandler(CallItem anItem, MultiCommandUtil aMultiUtil, String lightId, int intensity,
Integer targetBri,Integer targetBriInc, DeviceDescriptor device, String body) {
- // Not a device handler
- return null;
+ Devices theDomoticzApiResponse = null;
+ String responseString = null;
+
+ String theUrl = anItem.getItem().getAsString();
+ if(theUrl != null && !theUrl.isEmpty () && (theUrl.startsWith("http://") || theUrl.startsWith("https://"))) {
+ String intermediate = theUrl.substring(theUrl.indexOf("://") + 3);
+ String hostPortion = intermediate.substring(0, intermediate.indexOf('/'));
+ String theUrlBody = intermediate.substring(intermediate.indexOf('/') + 1);
+ String hostAddr = null;
+ if (hostPortion.contains(":")) {
+ hostAddr = hostPortion.substring(0, intermediate.indexOf(':'));
+ } else
+ hostAddr = hostPortion;
+ DomoticzHandler theHandler = findHandlerByAddress(hostAddr);
+ if(theHandler != null){
+ String theData;
+ String anUrl = BrightnessDecode.calculateReplaceIntensityValue(theUrlBody,
+ intensity, targetBri, targetBriInc, false);
+ theData = httpClient.doHttpRequest(theHandler.buildUrl(anUrl), null, null, null, theHandler.buildHeaders());
+ try {
+ theDomoticzApiResponse = new Gson().fromJson(theData, Devices.class);
+ if(theDomoticzApiResponse.getStatus().equals("OK"))
+ responseString = null;
+ else {
+ log.warn("Call failed for Domoticz " + theHandler.getDomoticzAddress().getName() + " with status " + theDomoticzApiResponse.getStatus() + " for item " + theDomoticzApiResponse.getTitle());
+ responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
+ "Error on calling url to change device state", "/lights/"
+ + lightId + "state", null, null).getTheErrors(), HueError[].class);
+ }
+ } catch (Exception e) {
+ log.warn("Cannot interrpret result from call for Domoticz " + theHandler.getDomoticzAddress().getName() + " as response is not parsable.");
+ responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
+ "Error on calling url to change device state", "/lights/"
+ + lightId + "state", null, null).getTheErrors(), HueError[].class);
+ }
+ } else {
+ log.warn("Domoticz Call could not complete, no address found: " + theUrl);
+ responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
+ "Error on calling url to change device state", "/lights/"
+ + lightId + "state", null, null).getTheErrors(), HueError[].class);
+ }
+ } else {
+ log.warn("Domoticz Call to be presented as http(s)://(:)/payload, format of request unknown: " + theUrl);
+ responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
+ "Error on calling url to change device state", "/lights/"
+ + lightId + "state", null, null).getTheErrors(), HueError[].class);
+ }
+ return responseString;
}
@Override
@@ -76,6 +128,7 @@ public class DomoticzHome implements Home {
log.info("Domoticz Home created." + (validDomoticz ? "" : " No Domoticz devices configured."));
if(!validDomoticz)
return null;
+ httpClient = new HTTPHandler();
domoticzs = new HashMap();
Iterator theList = bridgeSettings.getDomoticzaddress().getDevices().iterator();
while(theList.hasNext()) {
@@ -90,9 +143,25 @@ public class DomoticzHome implements Home {
return this;
}
+ private DomoticzHandler findHandlerByAddress(String hostAddress) {
+ DomoticzHandler aHandler = null;
+ boolean found = false;
+ Iterator keys = domoticzs.keySet().iterator();
+ while(keys.hasNext()) {
+ String key = keys.next();
+ aHandler = domoticzs.get(key);
+ if(aHandler != null && aHandler.getDomoticzAddress().getIp().equals(hostAddress)) {
+ found = true;
+ break;
+ }
+ }
+ if(!found)
+ aHandler = null;
+ return aHandler;
+ }
@Override
public void closeHome() {
- // noop
+ httpClient.closeHandler();
}
}
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..5a78902 100644
--- a/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHandler.java
+++ b/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHandler.java
@@ -4,6 +4,7 @@ import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
+
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
@@ -11,20 +12,20 @@ import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.ssl.SSLContexts;
+
import org.apache.http.HttpResponse;
-import org.apache.http.client.HttpClient;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpUriRequest;
-import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
-import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -33,23 +34,23 @@ import com.bwssystems.HABridge.api.NameValue;
public class HTTPHandler {
private static final Logger log = LoggerFactory.getLogger(HTTPHandler.class);
- private HttpClient httpClient;
-// private CloseableHttpClient httpclientSSL;
+// private HttpClient httpClient;
+ private CloseableHttpClient httpClient;
// private SSLContext sslcontext;
// private SSLConnectionSocketFactory sslsf;
-// private RequestConfig globalConfig;
+ private RequestConfig globalConfig;
public HTTPHandler() {
- httpClient = HttpClients.createDefault();
+// httpClient = HttpClients.createDefault();
// Removed Specific SSL as Apache HttpClient automatically uses SSL if the URI starts with https://
// Trust own CA and all self-signed certs
// sslcontext = SSLContexts.createDefault();
// Allow TLSv1 protocol only
// sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLS" }, null,
// SSLConnectionSocketFactory.getDefaultHostnameVerifier());
-// globalConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build();
-// httpclientSSL = HttpClients.custom().setSSLSocketFactory(sslsf).setDefaultRequestConfig(globalConfig).build();
+ globalConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build();
+ httpClient = HttpClients.custom().setDefaultRequestConfig(globalConfig).build();
}
@@ -125,8 +126,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);
@@ -134,23 +143,22 @@ public class HTTPHandler {
return theContent;
}
- public HttpClient getHttpClient() {
+// public HttpClient getHttpClient() {
+// return httpClient;
+// }
+
+
+ public CloseableHttpClient getHttpClient() {
return httpClient;
}
-// public CloseableHttpClient getHttpclientSSL() {
-// return httpclientSSL;
-// }
-
-
public void closeHandler() {
+ try {
+ httpClient.close();
+ } catch (IOException e) {
+ // noop
+ }
httpClient = null;
-// try {
-// httpclientSSL.close();
-// } catch (IOException e) {
-// // noop
-// }
-// httpclientSSL = null;
}
}
diff --git a/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHome.java b/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHome.java
index 97cb753..985fd7e 100644
--- a/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHome.java
+++ b/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHome.java
@@ -29,23 +29,25 @@ public class HTTPHome implements Home {
Integer targetBri,Integer targetBriInc, DeviceDescriptor device, String body) {
String responseString = null;
- //Backwards Compatibility Items
- if(anItem.getHttpVerb() == null || anItem.getHttpVerb().isEmpty())
- {
- if(device.getHttpVerb() != null && !device.getHttpVerb().isEmpty())
- anItem.setHttpVerb(device.getHttpVerb());
- }
+ String theUrl = anItem.getItem().getAsString();
+ if(theUrl != null && !theUrl.isEmpty () && (theUrl.startsWith("http://") || theUrl.startsWith("https://"))) {
+ //Backwards Compatibility Items
+ if(anItem.getHttpVerb() == null || anItem.getHttpVerb().isEmpty())
+ {
+ if(device.getHttpVerb() != null && !device.getHttpVerb().isEmpty())
+ anItem.setHttpVerb(device.getHttpVerb());
+ }
+
+ if(anItem.getHttpHeaders() == null || anItem.getHttpHeaders().isEmpty()) {
+ if(device.getHeaders() != null && !device.getHeaders().isEmpty() )
+ anItem.setHttpHeaders(device.getHeaders());
+ }
+
+ log.debug("executing HUE api request to Http "
+ + (anItem.getHttpVerb() == null ? "GET" : anItem.getHttpVerb()) + ": "
+ + anItem.getItem().getAsString());
- if(anItem.getHttpHeaders() == null || anItem.getHttpHeaders().isEmpty()) {
- if(device.getHeaders() != null && !device.getHeaders().isEmpty() )
- anItem.setHttpHeaders(device.getHeaders());
- }
-
- log.debug("executing HUE api request to Http "
- + (anItem.getHttpVerb() == null ? "GET" : anItem.getHttpVerb()) + ": "
- + anItem.getItem().getAsString());
-
- String anUrl = BrightnessDecode.calculateReplaceIntensityValue(anItem.getItem().getAsString(),
+ String anUrl = BrightnessDecode.calculateReplaceIntensityValue(theUrl,
intensity, targetBri, targetBriInc, false);
anUrl = TimeDecode.replaceTimeValue(anUrl);
@@ -63,6 +65,13 @@ public class HTTPHome implements Home {
"Error on calling url to change device state", "/lights/"
+ lightId + "state", null, null).getTheErrors(), HueError[].class);
}
+ } else {
+ log.warn("HTTP Call to be presented as http(s)://(:)/payload, format of request unknown: " + theUrl);
+ responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
+ "Error on calling url to change device state", "/lights/"
+ + lightId + "state", null, null).getTheErrors(), HueError[].class);
+ }
+
return responseString;
}
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..ea99d9d
--- /dev/null
+++ b/src/main/java/com/bwssystems/HABridge/plugins/lifx/LifxDevice.java
@@ -0,0 +1,49 @@
+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());
+ 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;
+ }
+ 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..831095d
--- /dev/null
+++ b/src/main/java/com/bwssystems/HABridge/plugins/lifx/LifxEntry.java
@@ -0,0 +1,25 @@
+package com.bwssystems.HABridge.plugins.lifx;
+
+public class LifxEntry {
+ private String name;
+ private String id;
+ private String type;
+ 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;
+ }
+ public String getType() {
+ return type;
+ }
+ public void setType(String type) {
+ this.type = type;
+ }
+}
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..51a002e
--- /dev/null
+++ b/src/main/java/com/bwssystems/HABridge/plugins/lifx/LifxHome.java
@@ -0,0 +1,257 @@
+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;
+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.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 static final float DIM_DIVISOR = (float)254.00;
+ private Map lifxMap;
+ private LFXClient client;
+ 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....");
+ 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;
+ }
+ }
+ }
+ if(bcastInetAddr != null) {
+ lifxMap = new HashMap();
+ 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);
+ aGsonHandler =
+ new GsonBuilder()
+ .create();
+ } else {
+ log.warn("Could not open LIFX, no bcast addr available, check your upnp config address.");
+ client = null;
+ validLifx = false;
+ return this;
+ }
+ } catch (IOException e) {
+ log.warn("Could not open LIFX, with IO Exception", e);
+ client = null;
+ validLifx = false;
+ return this;
+ } catch (InterruptedException e) {
+ log.warn("Could not open LIFX, with Interruprted Exception", e);
+ client = null;
+ validLifx = false;
+ return this;
+ }
+ }
+ 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;
+ 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");
+ 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);
+ 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) {
+ 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"))
+ theGroup.setPower(true);
+ if(body.contains("false"))
+ theGroup.setPower(false);
+ }
+ }
+ }
+ return theReturn;
+ }
+
+ @Override
+ public void closeHome() {
+ if(!validLifx)
+ 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/java/com/bwssystems/HABridge/plugins/tcp/TCPHome.java b/src/main/java/com/bwssystems/HABridge/plugins/tcp/TCPHome.java
index 52e94bc..5fb124b 100644
--- a/src/main/java/com/bwssystems/HABridge/plugins/tcp/TCPHome.java
+++ b/src/main/java/com/bwssystems/HABridge/plugins/tcp/TCPHome.java
@@ -32,41 +32,45 @@ public class TCPHome implements Home {
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 TCP: " + anItem.getItem().getAsString());
- String intermediate = anItem.getItem().getAsString().substring(anItem.getItem().getAsString().indexOf("://") + 3);
- String hostPortion = intermediate.substring(0, intermediate.indexOf('/'));
- String theUrlBody = intermediate.substring(intermediate.indexOf('/') + 1);
- String hostAddr = null;
- String port = null;
- InetAddress IPAddress = null;
- if (hostPortion.contains(":")) {
- hostAddr = hostPortion.substring(0, intermediate.indexOf(':'));
- port = hostPortion.substring(intermediate.indexOf(':') + 1);
+ String theUrl = anItem.getItem().getAsString();
+ if(theUrl != null && !theUrl.isEmpty () && theUrl.startsWith("tcp://")) {
+ String intermediate = theUrl.substring(theUrl.indexOf("://") + 3);
+ String hostPortion = intermediate.substring(0, intermediate.indexOf('/'));
+ String theUrlBody = intermediate.substring(intermediate.indexOf('/') + 1);
+ String hostAddr = null;
+ String port = null;
+ InetAddress IPAddress = null;
+ if (hostPortion.contains(":")) {
+ hostAddr = hostPortion.substring(0, intermediate.indexOf(':'));
+ port = hostPortion.substring(intermediate.indexOf(':') + 1);
+ } else
+ hostAddr = hostPortion;
+ try {
+ IPAddress = InetAddress.getByName(hostAddr);
+ } catch (UnknownHostException e) {
+ // noop
+ }
+
+ theUrlBody = TimeDecode.replaceTimeValue(theUrlBody);
+ if (theUrlBody.startsWith("0x")) {
+ theUrlBody = BrightnessDecode.calculateReplaceIntensityValue(theUrlBody, intensity, targetBri, targetBriInc, true);
+ sendData = DatatypeConverter.parseHexBinary(theUrlBody.substring(2));
+ } else {
+ theUrlBody = BrightnessDecode.calculateReplaceIntensityValue(theUrlBody, intensity, targetBri, targetBriInc, false);
+ sendData = theUrlBody.getBytes();
+ }
+
+ try {
+ Socket dataSendSocket = new Socket(IPAddress, Integer.parseInt(port));
+ DataOutputStream outToClient = new DataOutputStream(dataSendSocket.getOutputStream());
+ outToClient.write(sendData);
+ outToClient.flush();
+ dataSendSocket.close();
+ } catch (Exception e) {
+ // noop
+ }
} else
- hostAddr = hostPortion;
- try {
- IPAddress = InetAddress.getByName(hostAddr);
- } catch (UnknownHostException e) {
- // noop
- }
-
- theUrlBody = TimeDecode.replaceTimeValue(theUrlBody);
- if (theUrlBody.startsWith("0x")) {
- theUrlBody = BrightnessDecode.calculateReplaceIntensityValue(theUrlBody, intensity, targetBri, targetBriInc, true);
- sendData = DatatypeConverter.parseHexBinary(theUrlBody.substring(2));
- } else {
- theUrlBody = BrightnessDecode.calculateReplaceIntensityValue(theUrlBody, intensity, targetBri, targetBriInc, false);
- sendData = theUrlBody.getBytes();
- }
-
- try {
- Socket dataSendSocket = new Socket(IPAddress, Integer.parseInt(port));
- DataOutputStream outToClient = new DataOutputStream(dataSendSocket.getOutputStream());
- outToClient.write(sendData);
- outToClient.flush();
- dataSendSocket.close();
- } catch (Exception e) {
- // noop
- }
+ log.warn("Tcp Call to be presented as tcp://:/payload, format of request unknown: " + theUrl);
return null;
}
diff --git a/src/main/java/com/bwssystems/HABridge/plugins/udp/UDPHome.java b/src/main/java/com/bwssystems/HABridge/plugins/udp/UDPHome.java
index 3669081..b93a72e 100644
--- a/src/main/java/com/bwssystems/HABridge/plugins/udp/UDPHome.java
+++ b/src/main/java/com/bwssystems/HABridge/plugins/udp/UDPHome.java
@@ -33,39 +33,44 @@ public class UDPHome implements Home {
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 UDP: " + anItem.getItem().getAsString());
- String intermediate = anItem.getItem().getAsString().substring(anItem.getItem().getAsString().indexOf("://") + 3);
- String hostPortion = intermediate.substring(0, intermediate.indexOf('/'));
- String theUrlBody = intermediate.substring(intermediate.indexOf('/') + 1);
- String hostAddr = null;
- String port = null;
- InetAddress IPAddress = null;
- if (hostPortion.contains(":")) {
- hostAddr = hostPortion.substring(0, intermediate.indexOf(':'));
- port = hostPortion.substring(intermediate.indexOf(':') + 1);
+ String theUrl = anItem.getItem().getAsString();
+ if(theUrl != null && !theUrl.isEmpty () && theUrl.startsWith("udp://")) {
+ String intermediate = theUrl.substring(theUrl.indexOf("://") + 3);
+ String hostPortion = intermediate.substring(0, intermediate.indexOf('/'));
+ String theUrlBody = intermediate.substring(intermediate.indexOf('/') + 1);
+ String hostAddr = null;
+ String port = null;
+ InetAddress IPAddress = null;
+ if (hostPortion.contains(":")) {
+ hostAddr = hostPortion.substring(0, intermediate.indexOf(':'));
+ port = hostPortion.substring(intermediate.indexOf(':') + 1);
+ } else
+ hostAddr = hostPortion;
+ try {
+ IPAddress = InetAddress.getByName(hostAddr);
+ } catch (UnknownHostException e) {
+ log.warn("Udp Call, unknown host, continuing...");
+ return null;
+ }
+
+ theUrlBody = TimeDecode.replaceTimeValue(theUrlBody);
+ if (theUrlBody.startsWith("0x")) {
+ theUrlBody = BrightnessDecode.calculateReplaceIntensityValue(theUrlBody, intensity, targetBri, targetBriInc, true);
+ sendData = DatatypeConverter.parseHexBinary(theUrlBody.substring(2));
+ } else {
+ theUrlBody = BrightnessDecode.calculateReplaceIntensityValue(theUrlBody, intensity, targetBri, targetBriInc, false);
+ sendData = theUrlBody.getBytes();
+ }
+ try {
+ theUDPDatagramSender.sendUDPResponse(sendData, IPAddress, Integer.parseInt(port));
+ } catch (NumberFormatException e) {
+ log.warn("Udp Call, Number format exception on port, continuing...");
+ } catch (IOException e) {
+ log.warn("IO exception on udp call, continuing...");
+ }
} else
- hostAddr = hostPortion;
- try {
- IPAddress = InetAddress.getByName(hostAddr);
- } catch (UnknownHostException e) {
- log.warn("Udp Call, unknown host, continuing...");
- return null;
- }
+ log.warn("Udp Call to be presented as udp://:/payload, format of request unknown: " + theUrl);
- theUrlBody = TimeDecode.replaceTimeValue(theUrlBody);
- if (theUrlBody.startsWith("0x")) {
- theUrlBody = BrightnessDecode.calculateReplaceIntensityValue(theUrlBody, intensity, targetBri, targetBriInc, true);
- sendData = DatatypeConverter.parseHexBinary(theUrlBody.substring(2));
- } else {
- theUrlBody = BrightnessDecode.calculateReplaceIntensityValue(theUrlBody, intensity, targetBri, targetBriInc, false);
- sendData = theUrlBody.getBytes();
- }
- try {
- theUDPDatagramSender.sendUDPResponse(sendData, IPAddress, Integer.parseInt(port));
- } catch (NumberFormatException e) {
- log.warn("Udp Call, Number format exception on port, continuing...");
- } catch (IOException e) {
- log.warn("IO exception on udp call, continuing...");
- }
return null;
}
diff --git a/src/main/resources/public/scripts/app.js b/src/main/resources/public/scripts/app.js
index 4b305ed..20d5f94 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: 'LifxController'
}).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: "./api/devices", bridgelocation: ".", systemsbase: "./system", huebase: "./api", configs: [], backups: [], devices: [], device: {}, mapandid: [], type: "", settings: [], myToastMsg: [], logMsgs: [], loggerInfo: [], mapTypes: [], olddevicename: "", logShowAll: false, isInControl: false, showVera: false, showHarmony: false, showNest: false, showHue: false, showHal: false, showMqtt: false, showHass: false, showDomoticz: false, habridgeversion: ""};
+ this.state = {base: "./api/devices", bridgelocation: ".", systemsbase: "./system", huebase: "./api", configs: [], backups: [], devices: [], device: {}, mapandid: [], type: "", settings: [], myToastMsg: [], logMsgs: [], loggerInfo: [], mapTypes: [], olddevicename: "", logShowAll: false, isInControl: false, showVera: false, 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.showLifx = self.state.settings.lifxconfigured;
+ return;
+ }
+
this.loadBridgeSettings = function () {
return $http.get(this.state.systemsbase + "/settings").then(
function (response) {
@@ -269,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);
@@ -450,6 +459,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("{"))
@@ -1205,7 +1227,7 @@ app.controller('VeraController', function ($scope, $location, $http, bridgeServi
$scope.device = bridgeService.state.device;
};
- $scope.buildDeviceUrls = function (veradevice, dim_control) {
+ $scope.buildDeviceUrls = function (veradevice, dim_control, buildonly) {
if(dim_control.indexOf("byte") >= 0 || dim_control.indexOf("percent") >= 0 || dim_control.indexOf("math") >= 0) {
dimpayload = "http://" + veradevice.veraaddress + ":" + $scope.vera.port
+ "/data_request?id=action&output_format=json&DeviceNum="
@@ -1226,8 +1248,10 @@ app.controller('VeraController', function ($scope, $location, $http, bridgeServi
bridgeService.buildUrls(onpayload, dimpayload, offpayload, false, veradevice.id, veradevice.name, veradevice.veraname, "switch", "veraDevice", null, null);
$scope.device = bridgeService.state.device;
- bridgeService.editNewDevice($scope.device);
- $location.path('/editdevice');
+ if (!buildonly) {
+ bridgeService.editNewDevice($scope.device);
+ $location.path('/editdevice');
+ }
};
$scope.buildSceneUrls = function (verascene) {
@@ -1246,10 +1270,11 @@ app.controller('VeraController', function ($scope, $location, $http, bridgeServi
$scope.bulkAddDevices = function(dim_control) {
var devicesList = [];
+ $scope.clearDevice();
for(var i = 0; i < $scope.bulk.devices.length; i++) {
for(var x = 0; x < bridgeService.state.veradevices.length; x++) {
if(bridgeService.state.veradevices[x].id === $scope.bulk.devices[i]) {
- $scope.buildDeviceUrls(bridgeService.state.veradevices[x],dim_control);
+ $scope.buildDeviceUrls(bridgeService.state.veradevices[x],dim_control,true);
devicesList[i] = {
name: $scope.device.name,
mapId: $scope.device.mapId,
@@ -1266,6 +1291,7 @@ app.controller('VeraController', function ($scope, $location, $http, bridgeServi
contentBodyDim: $scope.device.contentBodyDim,
contentBodyOff: $scope.device.contentBodyOff
};
+ $scope.clearDevice();
}
}
}
@@ -1309,7 +1335,7 @@ app.controller('VeraController', function ($scope, $location, $http, bridgeServi
else {
$scope.selectAll = true;
for(var x = 0; x < bridgeService.state.veradevices.length; x++) {
- if($scope.bulk.devices.indexOf(bridgeService.state.veradevices[x]) < 0 && !bridgeService.findDeviceByMapId(bridgeService.state.veradevices[x].id, bridgeService.state.veradevices[x].veraname, "veraDevice"))
+ if($scope.bulk.devices.indexOf(bridgeService.state.veradevices[x]) < 0)
$scope.bulk.devices.push(bridgeService.state.veradevices[x].id);
}
}
@@ -1519,16 +1545,19 @@ app.controller('HueController', function ($scope, $location, $http, bridgeServic
offpayload = "{\"ipAddress\":\"" + huedevice.hueaddress + "\",\"deviceId\":\"" + huedevice.huedeviceid +"\",\"hueName\":\"" + huedevice.huename + "\"}";
bridgeService.buildUrls(onpayload, null, offpayload, true, huedevice.device.uniqueid, huedevice.device.name, huedevice.huename, "passthru", "hueDevice", null, null);
$scope.device = bridgeService.state.device;
- bridgeService.editNewDevice($scope.device);
- $location.path('/editdevice');
+ if (!buildonly) {
+ bridgeService.editNewDevice($scope.device);
+ $location.path('/editdevice');
+ }
};
$scope.bulkAddDevices = function() {
var devicesList = [];
+ $scope.clearDevice();
for(var i = 0; i < $scope.bulk.devices.length; i++) {
for(var x = 0; x < bridgeService.state.huedevices.length; x++) {
if(bridgeService.state.huedevices[x].device.uniqueid === $scope.bulk.devices[i]) {
- $scope.buildDeviceUrls(bridgeService.state.huedevices[x]);
+ $scope.buildDeviceUrls(bridgeService.state.huedevices[x],true);
devicesList[i] = {
name: $scope.device.name,
mapId: $scope.device.mapId,
@@ -1545,6 +1574,7 @@ app.controller('HueController', function ($scope, $location, $http, bridgeServic
contentBodyDim: $scope.device.contentBodyDim,
contentBodyOff: $scope.device.contentBodyOff
};
+ $scope.clearDevice();
}
}
}
@@ -1632,7 +1662,7 @@ app.controller('HalController', function ($scope, $location, $http, bridgeServic
$scope.device = bridgeService.state.device;
};
- $scope.buildDeviceUrls = function (haldevice, dim_control) {
+ $scope.buildDeviceUrls = function (haldevice, dim_control, buildonly) {
var preOnCmd = "";
var preDimCmd = "";
var preOffCmd = "";
@@ -1687,11 +1717,13 @@ app.controller('HalController', function ($scope, $location, $http, bridgeServic
+ postCmd;
bridgeService.buildUrls(onpayload, dimpayload, offpayload, false, haldevice.haldevicename + "-" + haldevice.halname, haldevice.haldevicename, haldevice.halname, aDeviceType, "halDevice", null, null);
$scope.device = bridgeService.state.device;
- bridgeService.editNewDevice($scope.device);
- $location.path('/editdevice');
+ if (!buildonly) {
+ bridgeService.editNewDevice($scope.device);
+ $location.path('/editdevice');
+ }
};
- $scope.buildButtonUrls = function (haldevice, onbutton, offbutton) {
+ $scope.buildButtonUrls = function (haldevice, onbutton, offbutton, buildonly) {
var actionOn = angular.fromJson(onbutton);
var actionOff = angular.fromJson(offbutton);
onpayload = "http://" + haldevice.haladdress + "/IrService!IrCmd=Set!IrDevice=" + haldevice.haldevicename.replaceAll(" ", "%20") + "!IrButton=" + actionOn.DeviceName.replaceAll(" ", "%20") + "?Token=" + $scope.bridge.settings.haltoken;
@@ -1699,20 +1731,24 @@ app.controller('HalController', function ($scope, $location, $http, bridgeServic
bridgeService.buildUrls(onpayload, null, offpayload, false, haldevice.haldevicename + "-" + haldevice.halname + "-" + actionOn.DeviceName, haldevice.haldevicename, haldevice.halname, "button", "halButton", null, null);
$scope.device = bridgeService.state.device;
- bridgeService.editNewDevice($scope.device);
- $location.path('/editdevice');
+ if (!buildonly) {
+ bridgeService.editNewDevice($scope.device);
+ $location.path('/editdevice');
+ }
};
- $scope.buildHALHomeUrls = function (haldevice) {
+ $scope.buildHALHomeUrls = function (haldevice, buildonly) {
onpayload = "http://" + haldevice.haladdress + "/ModeService!ModeCmd=Set!ModeName=Home?Token=" + $scope.bridge.settings.haltoken;
offpayload = "http://" + haldevice.haladdress + "/ModeService!ModeCmd=Set!ModeName=Away?Token=" + $scope.bridge.settings.haltoken;
bridgeService.buildUrls(onpayload, null, offpayload, false, haldevice.haldevicename + "-" + haldevice.halname + "-HomeAway", haldevice.haldevicename, haldevice.halname, "home", "halHome", null, null);
$scope.device = bridgeService.state.device;
- bridgeService.editNewDevice($scope.device);
- $location.path('/editdevice');
+ if (!buildonly) {
+ bridgeService.editNewDevice($scope.device);
+ $location.path('/editdevice');
+ }
};
- $scope.buildHALHeatUrls = function (haldevice) {
+ $scope.buildHALHeatUrls = function (haldevice, buildonly) {
onpayload = "http://" + haldevice.haladdress
+ "/HVACService!HVACCmd=Set!HVACName="
+ haldevice.haldevicename.replaceAll(" ", "%20")
@@ -1730,11 +1766,13 @@ app.controller('HalController', function ($scope, $location, $http, bridgeServic
+ $scope.bridge.settings.haltoken;
bridgeService.buildUrls(onpayload, dimpayload, offpayload, false, haldevice.haldevicename + "-" + haldevice.halname + "-SetHeat", haldevice.haldevicename + " Heat", haldevice.halname, "thermo", "halThermoSet", null, null);
$scope.device = bridgeService.state.device;
- bridgeService.editNewDevice($scope.device);
- $location.path('/editdevice');
+ if (!buildonly) {
+ bridgeService.editNewDevice($scope.device);
+ $location.path('/editdevice');
+ }
};
- $scope.buildHALCoolUrls = function (haldevice) {
+ $scope.buildHALCoolUrls = function (haldevice, buildonly) {
onpayload = "http://" + haldevice.haladdress
+ "/HVACService!HVACCmd=Set!HVACName="
+ haldevice.haldevicename.replaceAll(" ", "%20")
@@ -1752,11 +1790,13 @@ app.controller('HalController', function ($scope, $location, $http, bridgeServic
+ $scope.bridge.settings.haltoken;
bridgeService.buildUrls(onpayload, dimpayload, offpayload, false, haldevice.haldevicename + "-" + haldevice.halname + "-SetCool", haldevice.haldevicename + " Cool", haldevice.halname, "thermo", "halThermoSet", null, null);
$scope.device = bridgeService.state.device;
- bridgeService.editNewDevice($scope.device);
- $location.path('/editdevice');
+ if (!buildonly) {
+ bridgeService.editNewDevice($scope.device);
+ $location.path('/editdevice');
+ }
};
- $scope.buildHALAutoUrls = function (haldevice) {
+ $scope.buildHALAutoUrls = function (haldevice, buildonly) {
onpayload = "http://" + haldevice.haladdress
+ "/HVACService!HVACCmd=Set!HVACName="
+ haldevice.haldevicename.replaceAll(" ", "%20")
@@ -1768,11 +1808,13 @@ app.controller('HalController', function ($scope, $location, $http, bridgeServic
+ "!HVACMode=Off?Token="
bridgeService.buildUrls(onpayload, null, offpayload, false, haldevice.haldevicename + "-" + haldevice.halname + "-SetAuto", haldevice.haldevicename + " Auto", haldevice.halname, "thermo", "halThermoSet", null, null);
$scope.device = bridgeService.state.device;
- bridgeService.editNewDevice($scope.device);
- $location.path('/editdevice');
+ if (!buildonly) {
+ bridgeService.editNewDevice($scope.device);
+ $location.path('/editdevice');
+ }
};
- $scope.buildHALOffUrls = function (haldevice) {
+ $scope.buildHALOffUrls = function (haldevice, buildonly) {
onpayload = "http://" + haldevice.haladdress
+ "/HVACService!HVACCmd=Set!HVACName="
+ haldevice.haldevicename.replaceAll(" ", "%20")
@@ -1785,11 +1827,13 @@ app.controller('HalController', function ($scope, $location, $http, bridgeServic
$scope.device.offUrl = "http://" + haldevice.haladdress
bridgeService.buildUrls(onpayload, null, offpayload, false, haldevice.haldevicename + "-" + haldevice.halname + "-TurnOff", haldevice.haldevicename + " Thermostat", haldevice.halname, "thermo", "halThermoSet", null, null);
$scope.device = bridgeService.state.device;
- bridgeService.editNewDevice($scope.device);
- $location.path('/editdevice');
+ if (!buildonly) {
+ bridgeService.editNewDevice($scope.device);
+ $location.path('/editdevice');
+ }
};
- $scope.buildHALFanUrls = function (haldevice) {
+ $scope.buildHALFanUrls = function (haldevice, buildonly) {
onpayload = "http://" + haldevice.haladdress
+ "/HVACService!HVACCmd=Set!HVACName="
+ haldevice.haldevicename.replaceAll(" ", "%20")
@@ -1802,21 +1846,24 @@ app.controller('HalController', function ($scope, $location, $http, bridgeServic
+ $scope.bridge.settings.haltoken;
bridgeService.buildUrls(onpayload, null, offpayload, false, haldevice.haldevicename + "-" + haldevice.halname + "-SetFan", haldevice.haldevicename + " Fan", haldevice.halname, "thermo", "halThermoSet", null, null);
$scope.device = bridgeService.state.device;
- bridgeService.editNewDevice($scope.device);
- $location.path('/editdevice');
+ if (!buildonly) {
+ bridgeService.editNewDevice($scope.device);
+ $location.path('/editdevice');
+ }
};
$scope.bulkAddDevices = function(dim_control) {
var devicesList = [];
+ $scope.clearDevice();
for(var i = 0; i < $scope.bulk.devices.length; i++) {
for(var x = 0; x < bridgeService.state.haldevices.length; x++) {
if(bridgeService.state.haldevices[x].haldevicename === $scope.bulk.devices[i]) {
if(bridgeService.state.haldevices[x].haldevicetype === "HVAC")
- $scope.buildHALAutoUrls(bridgeService.state.haldevices[x]);
+ $scope.buildHALAutoUrls(bridgeService.state.haldevices[x], true);
else if(bridgeService.state.haldevices[x].haldevicetype === "HOME")
- $scope.buildHALHomeUrls(bridgeService.state.haldevices[x]);
+ $scope.buildHALHomeUrls(bridgeService.state.haldevices[x], true);
else
- $scope.buildDeviceUrls(bridgeService.state.haldevices[x],dim_control);
+ $scope.buildDeviceUrls(bridgeService.state.haldevices[x],dim_control, true);
devicesList[i] = {
name: $scope.device.name,
mapId: $scope.device.mapId,
@@ -1833,6 +1880,7 @@ app.controller('HalController', function ($scope, $location, $http, bridgeServic
contentBodyDim: $scope.device.contentBodyDim,
contentBodyOff: $scope.device.contentBodyOff
};
+ $scope.clearDevice();
}
}
}
@@ -1875,7 +1923,7 @@ app.controller('HalController', function ($scope, $location, $http, bridgeServic
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"))
+ if($scope.bulk.devices.indexOf(bridgeService.state.haldevices[x]) < 0)
$scope.bulk.devices.push(bridgeService.state.haldevices[x].haldevicename);
}
}
@@ -1964,7 +2012,7 @@ app.controller('HassController', function ($scope, $location, $http, bridgeServi
$scope.device = bridgeService.state.device;
};
- $scope.buildDeviceUrls = function (hassdevice, dim_control) {
+ $scope.buildDeviceUrls = function (hassdevice, dim_control, buildonly) {
onpayload = "{\"entityId\":\"" + hassdevice.deviceState.entity_id + "\",\"hassName\":\"" + hassdevice.hassname + "\",\"state\":\"on\"}";
if((dim_control.indexOf("byte") >= 0 || dim_control.indexOf("percent") >= 0 || dim_control.indexOf("math") >= 0))
dimpayload = "{\"entityId\":\"" + hassdevice.deviceState.entity_id + "\",\"hassName\":\"" + hassdevice.hassname + "\",\"state\":\"on\",\"bri\":\"" + dim_control + "\"}";
@@ -1974,89 +2022,19 @@ app.controller('HassController', function ($scope, $location, $http, bridgeServi
bridgeService.buildUrls(onpayload, dimpayload, offpayload, true, hassdevice.hassname + "-" + hassdevice.deviceState.entity_id, hassdevice.deviceState.entity_id, hassdevice.hassname, hassdevice.domain, "hassDevice", null, null);
$scope.device = bridgeService.state.device;
- bridgeService.editNewDevice($scope.device);
- $location.path('/editdevice');
- };
-
- $scope.buildHassHeatUrls = function (hassdevice) {
- onpayload = "{\"entityId\":\"" + hassdevice.deviceState.entity_id + "\",\"hassName\":\"" + hassdevice.hassname + "\",\"state\":\"on\"}";
- if((dim_control.indexOf("byte") >= 0 || dim_control.indexOf("percent") >= 0 || dim_control.indexOf("math") >= 0))
- dimpayload = "{\"entityId\":\"" + hassdevice.deviceState.entity_id + "\",\"hassName\":\"" + hassdevice.hassname + "\",\"state\":\"on\",\"bri\":\"" + dim_control + "\"}";
- else
- dimpayload = "{\"entityId\":\"" + hassdevice.deviceState.entity_id + "\",\"hassName\":\"" + hassdevice.hassname + "\",\"state\":\"on\"}";
- offpayload = "{\"entityId\":\"" + hassdevice.deviceState.entity_id + "\",\"hassName\":\"" + hassdevice.hassname + "\",\"state\":\"off\"}";
-
- bridgeService.buildUrls(onpayload, dimpayload, offpayload, true, hassdevice.hassname + "-" + hassdevice.deviceState.entity_id, hassdevice.deviceState.entity_id, hassdevice.hassname, hassdevice.domain, "hassDevice", null, null);
- $scope.device = bridgeService.state.device;
- bridgeService.editNewDevice($scope.device);
- $location.path('/editdevice');
- };
-
- $scope.buildHassCoolUrls = function (hassdevice) {
- onpayload = "{\"entityId\":\"" + hassdevice.deviceState.entity_id + "\",\"hassName\":\"" + hassdevice.hassname + "\",\"state\":\"on\"}";
- if((dim_control.indexOf("byte") >= 0 || dim_control.indexOf("percent") >= 0 || dim_control.indexOf("math") >= 0))
- dimpayload = "{\"entityId\":\"" + hassdevice.deviceState.entity_id + "\",\"hassName\":\"" + hassdevice.hassname + "\",\"state\":\"on\",\"bri\":\"" + dim_control + "\"}";
- else
- dimpayload = "{\"entityId\":\"" + hassdevice.deviceState.entity_id + "\",\"hassName\":\"" + hassdevice.hassname + "\",\"state\":\"on\"}";
- offpayload = "{\"entityId\":\"" + hassdevice.deviceState.entity_id + "\",\"hassName\":\"" + hassdevice.hassname + "\",\"state\":\"off\"}";
-
- bridgeService.buildUrls(onpayload, dimpayload, offpayload, true, hassdevice.hassname + "-" + hassdevice.deviceState.entity_id, hassdevice.deviceState.entity_id, hassdevice.hassname, hassdevice.domain, "hassDevice", null, null);
- $scope.device = bridgeService.state.device;
- bridgeService.editNewDevice($scope.device);
- $location.path('/editdevice');
- };
-
- $scope.buildHassAutoUrls = function (hassdevice) {
- onpayload = "{\"entityId\":\"" + hassdevice.deviceState.entity_id + "\",\"hassName\":\"" + hassdevice.hassname + "\",\"state\":\"on\"}";
- if((dim_control.indexOf("byte") >= 0 || dim_control.indexOf("percent") >= 0 || dim_control.indexOf("math") >= 0))
- dimpayload = "{\"entityId\":\"" + hassdevice.deviceState.entity_id + "\",\"hassName\":\"" + hassdevice.hassname + "\",\"state\":\"on\",\"bri\":\"" + dim_control + "\"}";
- else
- dimpayload = "{\"entityId\":\"" + hassdevice.deviceState.entity_id + "\",\"hassName\":\"" + hassdevice.hassname + "\",\"state\":\"on\"}";
- offpayload = "{\"entityId\":\"" + hassdevice.deviceState.entity_id + "\",\"hassName\":\"" + hassdevice.hassname + "\",\"state\":\"off\"}";
-
- bridgeService.buildUrls(onpayload, dimpayload, offpayload, true, hassdevice.hassname + "-" + hassdevice.deviceState.entity_id, hassdevice.deviceState.entity_id, hassdevice.hassname, hassdevice.domain, "hassDevice", null, null);
- $scope.device = bridgeService.state.device;
- bridgeService.editNewDevice($scope.device);
- $location.path('/editdevice');
- };
-
- $scope.buildHassOffUrls = function (hassdevice) {
- onpayload = "{\"entityId\":\"" + hassdevice.deviceState.entity_id + "\",\"hassName\":\"" + hassdevice.hassname + "\",\"state\":\"on\"}";
- if((dim_control.indexOf("byte") >= 0 || dim_control.indexOf("percent") >= 0 || dim_control.indexOf("math") >= 0))
- dimpayload = "{\"entityId\":\"" + hassdevice.deviceState.entity_id + "\",\"hassName\":\"" + hassdevice.hassname + "\",\"state\":\"on\",\"bri\":\"" + dim_control + "\"}";
- else
- dimpayload = "{\"entityId\":\"" + hassdevice.deviceState.entity_id + "\",\"hassName\":\"" + hassdevice.hassname + "\",\"state\":\"on\"}";
- offpayload = "{\"entityId\":\"" + hassdevice.deviceState.entity_id + "\",\"hassName\":\"" + hassdevice.hassname + "\",\"state\":\"off\"}";
-
- bridgeService.buildUrls(onpayload, dimpayload, offpayload, true, hassdevice.hassname + "-" + hassdevice.deviceState.entity_id, hassdevice.deviceState.entity_id, hassdevice.hassname, hassdevice.domain, "hassDevice", null, null);
- $scope.device = bridgeService.state.device;
- bridgeService.editNewDevice($scope.device);
- $location.path('/editdevice');
- };
-
- $scope.buildHassFanUrls = function (hassdevice) {
- onpayload = "{\"entityId\":\"" + hassdevice.deviceState.entity_id + "\",\"hassName\":\"" + hassdevice.hassname + "\",\"state\":\"on\"}";
- if((dim_control.indexOf("byte") >= 0 || dim_control.indexOf("percent") >= 0 || dim_control.indexOf("math") >= 0))
- dimpayload = "{\"entityId\":\"" + hassdevice.deviceState.entity_id + "\",\"hassName\":\"" + hassdevice.hassname + "\",\"state\":\"on\",\"bri\":\"" + dim_control + "\"}";
- else
- dimpayload = "{\"entityId\":\"" + hassdevice.deviceState.entity_id + "\",\"hassName\":\"" + hassdevice.hassname + "\",\"state\":\"on\"}";
- offpayload = "{\"entityId\":\"" + hassdevice.deviceState.entity_id + "\",\"hassName\":\"" + hassdevice.hassname + "\",\"state\":\"off\"}";
-
- bridgeService.buildUrls(onpayload, dimpayload, offpayload, true, hassdevice.hassname + "-" + hassdevice.deviceState.entity_id, hassdevice.deviceState.entity_id, hassdevice.hassname, hassdevice.domain, "hassDevice", null, null);
- $scope.device = bridgeService.state.device;
- bridgeService.editNewDevice($scope.device);
- $location.path('/editdevice');
+ if (!buildonly) {
+ bridgeService.editNewDevice($scope.device);
+ $location.path('/editdevice');
+ }
};
$scope.bulkAddDevices = function(dim_control) {
var devicesList = [];
+ $scope.clearDevice();
for(var i = 0; i < $scope.bulk.devices.length; i++) {
for(var x = 0; x < bridgeService.state.hassdevices.length; x++) {
- if(bridgeService.state.hassdevices[x].deviceName === $scope.bulk.devices[i]) {
- if(bridgeService.state.hassdevices[x].domain === "climate")
- $scope.buildHassAutoUrls(bridgeService.state.hassdevices[x]);
- else
- $scope.buildDeviceUrls(bridgeService.state.hassdevices[x],dim_control);
+ if(bridgeService.state.hassdevices[x].deviceState.entity_id === $scope.bulk.devices[i] && bridgeService.state.hassdevices[x].domain !== "sensor" && bridgeService.state.hassdevices[x].domain !== "sun") {
+ $scope.buildDeviceUrls(bridgeService.state.hassdevices[x],dim_control,true);
devicesList[i] = {
name: $scope.device.name,
mapId: $scope.device.mapId,
@@ -2073,6 +2051,7 @@ app.controller('HassController', function ($scope, $location, $http, bridgeServi
contentBodyDim: $scope.device.contentBodyDim,
contentBodyOff: $scope.device.contentBodyOff
};
+ $scope.clearDevice();
}
}
}
@@ -2080,7 +2059,7 @@ app.controller('HassController', function ($scope, $location, $http, bridgeServi
function () {
$scope.clearDevice();
bridgeService.viewDevices();
- bridgeService.viewhassdevices();
+ bridgeService.viewHassDevices();
},
function (error) {
bridgeService.displayWarn("Error adding Hass devices in bulk.", error)
@@ -2115,8 +2094,8 @@ app.controller('HassController', function ($scope, $location, $http, bridgeServi
else {
$scope.selectAll = true;
for(var x = 0; x < bridgeService.state.hassdevices.length; x++) {
- if($scope.bulk.devices.indexOf(bridgeService.state.hassdevices[x]) < 0 && !bridgeService.findDeviceByMapId(bridgeService.state.hassdevices[x].hassdevicename + "-" + bridgeService.state.hassdevices[x].halname, bridgeService.state.hassdevices[x].halname, "hassdevice"))
- $scope.bulk.devices.push(bridgeService.state.hassdevices[x].hassdevicename);
+ if($scope.bulk.devices.indexOf(bridgeService.state.hassdevices[x].deviceState.entity_id) < 0 && bridgeService.state.hassdevices[x].domain !== "sensor" && bridgeService.state.hassdevices[x].domain !== "sun")
+ $scope.bulk.devices.push(bridgeService.state.hassdevices[x].deviceState.entity_id);
}
}
};
@@ -2159,7 +2138,7 @@ app.controller('DomoticzController', function ($scope, $location, $http, bridgeS
$scope.device = bridgeService.state.device;
};
- $scope.buildDeviceUrls = function (domoticzdevice, dim_control) {
+ $scope.buildDeviceUrls = function (domoticzdevice, dim_control, buildonly) {
var preCmd = "";
var postOnCmd = "";
var postDimCmd = "";
@@ -2198,16 +2177,19 @@ app.controller('DomoticzController', function ($scope, $location, $http, bridgeS
+ postOffCmd;
bridgeService.buildUrls(onpayload, dimpayload, offpayload, false, domoticzdevice.devicename + "-" + domoticzdevice.domoticzname, domoticzdevice.devicename, domoticzdevice.domoticzname, aDeviceType, "domoticzDevice", null, null);
$scope.device = bridgeService.state.device;
- bridgeService.editNewDevice($scope.device);
- $location.path('/editdevice');
+ if (!buildonly) {
+ bridgeService.editNewDevice($scope.device);
+ $location.path('/editdevice');
+ }
};
$scope.bulkAddDevices = function(dim_control) {
var devicesList = [];
+ $scope.clearDevice();
for(var i = 0; i < $scope.bulk.devices.length; i++) {
for(var x = 0; x < bridgeService.state.domoticzdevices.length; x++) {
if(bridgeService.state.domoticzdevices[x].devicename === $scope.bulk.devices[i]) {
- $scope.buildDeviceUrls(bridgeService.state.domoticzdevices[x],dim_control);
+ $scope.buildDeviceUrls(bridgeService.state.domoticzdevices[x],dim_control,true);
devicesList[i] = {
name: $scope.device.name,
mapId: $scope.device.mapId,
@@ -2224,6 +2206,7 @@ app.controller('DomoticzController', function ($scope, $location, $http, bridgeS
contentBodyDim: $scope.device.contentBodyDim,
contentBodyOff: $scope.device.contentBodyOff
};
+ $scope.clearDevice();
}
}
}
@@ -2234,7 +2217,7 @@ app.controller('DomoticzController', function ($scope, $location, $http, bridgeS
bridgeService.viewHalDevices();
},
function (error) {
- bridgeService.displayWarn("Error adding HAL devices in bulk.", error)
+ bridgeService.displayWarn("Error adding Domoticz devices in bulk.", error)
}
);
$scope.bulk = { devices: [] };
@@ -2266,8 +2249,130 @@ app.controller('DomoticzController', function ($scope, $location, $http, bridgeS
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);
+ if($scope.bulk.devices.indexOf(bridgeService.state.domoticzdevices[x]) < 0)
+ $scope.bulk.devices.push(bridgeService.state.domoticzdevices[x].devicename);
+ }
+ }
+ };
+
+ $scope.toggleButtons = function () {
+ $scope.buttonsVisible = !$scope.buttonsVisible;
+ if($scope.buttonsVisible)
+ $scope.imgButtonsUrl = "glyphicon glyphicon-minus";
+ else
+ $scope.imgButtonsUrl = "glyphicon glyphicon-plus";
+ };
+
+ $scope.deleteDevice = function (device) {
+ $scope.bridge.device = device;
+ ngDialog.open({
+ template: 'deleteDialog',
+ controller: 'DeleteDialogCtrl',
+ className: 'ngdialog-theme-default'
+ });
+ };
+
+ $scope.editDevice = function (device) {
+ bridgeService.editDevice(device);
+ $location.path('/editdevice');
+ };
+});
+
+app.controller('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, buildonly) {
+ dimpayload = angular.toJson(lifxdevice);
+ onpayload = angular.toJson(lifxdevice);
+ offpayload = angular.toJson(lifxdevice);
+ bridgeService.buildUrls(onpayload, dimpayload, offpayload, true, lifxdevice.name, lifxdevice.name, lifxdevice.name, null, "lifxDevice", null, null);
+ $scope.device = bridgeService.state.device;
+ if (!buildonly) {
+ bridgeService.editNewDevice($scope.device);
+ $location.path('/editdevice');
+ }
+ };
+
+ $scope.bulkAddDevices = function(dim_control) {
+ var devicesList = [];
+ $scope.clearDevice();
+ for(var i = 0; i < $scope.bulk.devices.length; i++) {
+ for(var x = 0; x < bridgeService.state.lifxdevices.length; x++) {
+ if(bridgeService.state.lifxdevices[x].devicename === $scope.bulk.devices[i]) {
+ $scope.buildDeviceUrls(bridgeService.state.lifxdevices[x],dim_control,true);
+ devicesList[i] = {
+ name: $scope.device.name,
+ mapId: $scope.device.mapId,
+ mapType: $scope.device.mapType,
+ deviceType: $scope.device.deviceType,
+ targetDevice: $scope.device.targetDevice,
+ onUrl: $scope.device.onUrl,
+ dimUrl: $scope.device.dimUrl,
+ offUrl: $scope.device.offUrl,
+ headers: $scope.device.headers,
+ httpVerb: $scope.device.httpVerb,
+ contentType: $scope.device.contentType,
+ contentBody: $scope.device.contentBody,
+ contentBodyDim: $scope.device.contentBodyDim,
+ contentBodyOff: $scope.device.contentBodyOff
+ };
+ $scope.clearDevice();
+ }
+ }
+ }
+ bridgeService.bulkAddDevice(devicesList).then(
+ function () {
+ $scope.clearDevice();
+ bridgeService.viewDevices();
+ bridgeService.viewHalDevices();
+ },
+ function (error) {
+ bridgeService.displayWarn("Error adding LIFX devices in bulk.", error)
+ }
+ );
+ $scope.bulk = { devices: [] };
+ $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.lifxdevices[x]) < 0)
+ $scope.bulk.devices.push(bridgeService.state.lifxdevices[x].devicename);
}
}
};
@@ -2566,6 +2671,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;
});
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..7f4f151 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
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 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:
@@ -45,7 +46,7 @@
Custom Math
- 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.
@@ -75,7 +76,7 @@
{{domoticzdevice.domoticzname}}
Build Item
+ ng-click="buildDeviceUrls(domoticzdevice, device_dim_control,false)">Build Item
diff --git a/src/main/resources/public/views/editdevice.html b/src/main/resources/public/views/editdevice.html
index 625a147..f380fdd 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
Add/Edit
@@ -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.