diff --git a/pom.xml b/pom.xml
index fdfdbb2..e8c94e8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
com.bwssystems.HABridge
ha-bridge
- 2.0.7-hal-f
+ 2.0.7-hal-g
jar
HA Bridge
diff --git a/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java b/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java
index 284b46c..c2c1f2a 100644
--- a/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java
+++ b/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java
@@ -1,6 +1,9 @@
package com.bwssystems.HABridge;
import java.util.List;
+import java.util.Map;
+
+import com.bwssystems.HABridge.api.hue.WhitelistEntry;
public class BridgeSettingsDescriptor {
private String upnpconfigaddress;
@@ -27,6 +30,7 @@ public class BridgeSettingsDescriptor {
private IpList haladdress;
private String haltoken;
private boolean halconfigured;
+ private Map whitelist;
public BridgeSettingsDescriptor() {
super();
@@ -188,6 +192,12 @@ public class BridgeSettingsDescriptor {
public void setHalconfigured(boolean halconfigured) {
this.halconfigured = halconfigured;
}
+ public Map getWhitelist() {
+ return whitelist;
+ }
+ public void setWhitelist(Map whitelist) {
+ this.whitelist = whitelist;
+ }
public Boolean isValidVera() {
if(this.getVeraAddress() == null || this.getVeraAddress().getDevices().size() <= 0)
return false;
diff --git a/src/main/java/com/bwssystems/HABridge/api/hue/HueApiResponse.java b/src/main/java/com/bwssystems/HABridge/api/hue/HueApiResponse.java
index f9c9533..dd137a4 100644
--- a/src/main/java/com/bwssystems/HABridge/api/hue/HueApiResponse.java
+++ b/src/main/java/com/bwssystems/HABridge/api/hue/HueApiResponse.java
@@ -18,9 +18,9 @@ public class HueApiResponse {
private Map rules;
private HueConfig config;
- public HueApiResponse(String name, String ipaddress, String devicetype, String userid) {
+ public HueApiResponse(String name, String ipaddress, Map awhitelist) {
super();
- this.setConfig(HueConfig.createConfig(name, ipaddress, devicetype, userid));
+ this.setConfig(HueConfig.createConfig(name, ipaddress, awhitelist));
this.setRules(new HashMap<>());
this.setSensors(new HashMap<>());
this.setSchedules(new HashMap<>());
diff --git a/src/main/java/com/bwssystems/HABridge/api/hue/HueConfig.java b/src/main/java/com/bwssystems/HABridge/api/hue/HueConfig.java
index fc7fc6b..e0cac47 100644
--- a/src/main/java/com/bwssystems/HABridge/api/hue/HueConfig.java
+++ b/src/main/java/com/bwssystems/HABridge/api/hue/HueConfig.java
@@ -35,7 +35,7 @@ public class HueConfig
private String replacesbridgeid;
private Map whitelist;
- public static HueConfig createConfig(String name, String ipaddress, String devicetype, String userid) {
+ public static HueConfig createConfig(String name, String ipaddress, Map awhitelist) {
HueConfig aConfig = new HueConfig();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
@@ -57,12 +57,10 @@ public class HueConfig
aConfig.setLocaltime(dateFormat.format(new Date()));
aConfig.setTimezone(TimeZone.getDefault().getID());
aConfig.setZigbeechannel("6");
- aConfig.setBridgeid("001788FFFE09A206");
+ aConfig.setBridgeid(HuePublicConfig.getBridgeIdFromMac(aConfig.getMac(), ipaddress));
aConfig.setModelid("BSB002");
aConfig.setFactorynew(false);
aConfig.setReplacesbridgeid(null);
- Map awhitelist = new HashMap<>();
- awhitelist.put(userid, WhitelistEntry.createEntry(devicetype));
aConfig.setWhitelist(awhitelist);
return aConfig;
diff --git a/src/main/java/com/bwssystems/HABridge/api/hue/HueError.java b/src/main/java/com/bwssystems/HABridge/api/hue/HueError.java
new file mode 100644
index 0000000..b4169b1
--- /dev/null
+++ b/src/main/java/com/bwssystems/HABridge/api/hue/HueError.java
@@ -0,0 +1,19 @@
+package com.bwssystems.HABridge.api.hue;
+
+public class HueError {
+
+ private HueErrorDetails error;
+
+ public HueError(HueErrorDetails error) {
+ super();
+ this.error = error;
+ }
+
+ public HueErrorDetails getError() {
+ return error;
+ }
+
+ public void setError(HueErrorDetails error) {
+ this.error = error;
+ }
+}
diff --git a/src/main/java/com/bwssystems/HABridge/api/hue/HueErrorDetails.java b/src/main/java/com/bwssystems/HABridge/api/hue/HueErrorDetails.java
new file mode 100644
index 0000000..5c3869d
--- /dev/null
+++ b/src/main/java/com/bwssystems/HABridge/api/hue/HueErrorDetails.java
@@ -0,0 +1,56 @@
+package com.bwssystems.HABridge.api.hue;
+
+public class HueErrorDetails {
+ private String type;
+ private String address;
+ private String description;
+ private String method_name;
+ private String resource_name;
+ private String value;
+ public HueErrorDetails(String type, String address, String description, String method_name, String resource_name,
+ String value) {
+ super();
+ this.type = type;
+ this.address = address;
+ this.description = description;
+ this.method_name = method_name;
+ this.resource_name = resource_name;
+ this.value = value;
+ }
+ public String getType() {
+ return type;
+ }
+ public void setType(String type) {
+ this.type = type;
+ }
+ public String getAddress() {
+ return address;
+ }
+ public void setAddress(String address) {
+ this.address = address;
+ }
+ public String getDescription() {
+ return description;
+ }
+ public void setDescription(String description) {
+ this.description = description;
+ }
+ public String getMethod_name() {
+ return method_name;
+ }
+ public void setMethod_name(String method_name) {
+ this.method_name = method_name;
+ }
+ public String getResource_name() {
+ return resource_name;
+ }
+ public void setResource_name(String resource_name) {
+ this.resource_name = resource_name;
+ }
+ public String getValue() {
+ return value;
+ }
+ public void setValue(String value) {
+ this.value = value;
+ }
+}
diff --git a/src/main/java/com/bwssystems/HABridge/api/hue/HueErrorResponse.java b/src/main/java/com/bwssystems/HABridge/api/hue/HueErrorResponse.java
new file mode 100644
index 0000000..3c2b479
--- /dev/null
+++ b/src/main/java/com/bwssystems/HABridge/api/hue/HueErrorResponse.java
@@ -0,0 +1,27 @@
+package com.bwssystems.HABridge.api.hue;
+
+import java.util.ArrayList;
+
+public class HueErrorResponse {
+ private ArrayList theErrors;
+
+ public HueErrorResponse() {
+ super();
+ theErrors = new ArrayList();
+ }
+
+ public void addError(HueError anError) {
+ theErrors.add(anError);
+ }
+
+ public HueError[] getTheErrors() {
+ HueError theList[] = new HueError[theErrors.size()];
+ theList = theErrors.toArray(theList);
+ return theList;
+ }
+
+ public void setTheErrors(ArrayList theErrors) {
+ this.theErrors = theErrors;
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/bwssystems/HABridge/api/hue/HuePublicConfig.java b/src/main/java/com/bwssystems/HABridge/api/hue/HuePublicConfig.java
new file mode 100644
index 0000000..c927446
--- /dev/null
+++ b/src/main/java/com/bwssystems/HABridge/api/hue/HuePublicConfig.java
@@ -0,0 +1,154 @@
+package com.bwssystems.HABridge.api.hue;
+
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.util.StringTokenizer;
+
+import javax.xml.bind.DatatypeConverter;
+
+public class HuePublicConfig
+{
+ private String name;
+ private String apiversion;
+ private String swversion;
+ private String mac;
+ private String bridgeid;
+ private String replacesbridgeid;
+ private Boolean factorynew;
+ private String modelid;
+
+ public static HuePublicConfig createConfig(String name, String ipaddress) {
+ HuePublicConfig aConfig = new HuePublicConfig();
+ aConfig.setMac(HuePublicConfig.getMacAddress(ipaddress));
+ aConfig.setApiversion("1.10.0");
+ aConfig.setSwversion("01028090");
+ aConfig.setName(name);
+ aConfig.setBridgeid(HuePublicConfig.getBridgeIdFromMac(aConfig.getMac(), ipaddress));
+ aConfig.setModelid("BSB002");
+ aConfig.setFactorynew(false);
+ aConfig.setReplacesbridgeid(null);
+
+ return aConfig;
+ }
+
+ private static String getMacAddress(String addr)
+ {
+ InetAddress ip;
+ StringBuilder sb = new StringBuilder();
+ try {
+
+ ip = InetAddress.getByName(addr);
+
+ NetworkInterface network = NetworkInterface.getByInetAddress(ip);
+
+ byte[] mac = network.getHardwareAddress();
+
+ for (int i = 0; i < mac.length; i++) {
+ sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? ":" : ""));
+ }
+
+ } catch (UnknownHostException e) {
+
+ sb.append("00:00:88:00:bb:ee");
+
+ } catch (SocketException e){
+
+ sb.append("00:00:88:00:bb:ee");
+
+ } catch (Exception e){
+
+ sb.append("00:00:88:00:bb:ee");
+
+ }
+
+ return sb.toString();
+ }
+
+ protected static String getBridgeIdFromMac(String macAddr, String ipAddr)
+ {
+ StringTokenizer st = new StringTokenizer(macAddr, ":");
+ String bridgeId = "";
+ String port = null;
+ while(st.hasMoreTokens()) {
+ bridgeId = bridgeId + st.nextToken();
+ }
+ if(ipAddr.contains(":")) {
+ port = ipAddr.substring(ipAddr.indexOf(":"));
+ BigInteger bigInt = BigInteger.valueOf(Integer.getInteger(port).intValue());
+ byte[] theBytes = bigInt.toByteArray();
+ bridgeId = bridgeId + DatatypeConverter.printHexBinary(theBytes);
+ }
+ else
+ bridgeId = bridgeId + "0800";
+ return bridgeId;
+ }
+
+ public String getMac() {
+ return mac;
+ }
+
+ public void setMac(String mac) {
+ this.mac = mac;
+ }
+
+ public String getSwversion() {
+ return swversion;
+ }
+
+ public void setSwversion(String swversion) {
+ this.swversion = swversion;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+
+ public String getApiversion() {
+ return apiversion;
+ }
+
+ public void setApiversion(String apiversion) {
+ this.apiversion = apiversion;
+ }
+
+
+ public String getModelid() {
+ return modelid;
+ }
+
+ public void setModelid(String modelid) {
+ this.modelid = modelid;
+ }
+
+ public String getBridgeid() {
+ return bridgeid;
+ }
+
+ public void setBridgeid(String bridgeid) {
+ this.bridgeid = bridgeid;
+ }
+
+ public Boolean getFactorynew() {
+ return factorynew;
+ }
+
+ public void setFactorynew(Boolean factorynew) {
+ this.factorynew = factorynew;
+ }
+
+ public String getReplacesbridgeid() {
+ return replacesbridgeid;
+ }
+
+ public void setReplacesbridgeid(String replacesbridgeid) {
+ this.replacesbridgeid = replacesbridgeid;
+ }
+}
diff --git a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java
index da00d50..3a6d7dd 100644
--- a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java
+++ b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java
@@ -7,7 +7,12 @@ import com.bwssystems.HABridge.api.UserCreateRequest;
import com.bwssystems.HABridge.api.hue.DeviceResponse;
import com.bwssystems.HABridge.api.hue.DeviceState;
import com.bwssystems.HABridge.api.hue.HueApiResponse;
+import com.bwssystems.HABridge.api.hue.HueError;
+import com.bwssystems.HABridge.api.hue.HueErrorDetails;
+import com.bwssystems.HABridge.api.hue.HueErrorResponse;
+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.NestBridge.NestInstruction;
import com.bwssystems.NestBridge.NestHome;
@@ -62,6 +67,8 @@ import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.UUID;
import javax.net.ssl.SSLContext;
import javax.xml.bind.DatatypeConverter;
@@ -137,30 +144,58 @@ public class HueMulator implements HueErrorStringSet {
get(HUE_CONTEXT + "/:userid/groups", "application/json", (request, response) -> {
String userId = request.params(":userid");
log.debug("hue groups list requested: " + userId + " from " + request.ip());
+ response.status(HttpStatus.SC_OK);
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
- return "";
- } , new JsonTransformer());
+ return "{}";
+ });
// http://ip_address:port/api/{userId}/groups/0 returns json objects of all groups configured
get(HUE_CONTEXT + "/:userid/groups/0", "application/json", (request, response) -> {
String userId = request.params(":userid");
log.debug("hue group 0 list requested: " + userId + " from " + request.ip());
+ response.status(HttpStatus.SC_OK);
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
- return "";
- } , new JsonTransformer());
+ return "[{\"error\":{\"type\":\"3\", \"address\": \"/api/" + userId + "/groups/" + "0" + "\",\"description\": \"Object not found\"}}]";
+ });
// http://ip_address:port/api/{userId}/scenes returns json objects of all scenes configured
get(HUE_CONTEXT + "/:userid/scenes", "application/json", (request, response) -> {
String userId = request.params(":userid");
log.debug("hue scenes list requested: " + userId + " from " + request.ip());
+ response.status(HttpStatus.SC_OK);
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
- return "";
- } , new JsonTransformer());
+ return "{}";
+ });
// http://ip_address:port/api/{userId}/schedules returns json objects of all schedules configured
get(HUE_CONTEXT + "/:userid/schedules", "application/json", (request, response) -> {
String userId = request.params(":userid");
log.debug("hue schedules list requested: " + userId + " from " + request.ip());
+ response.status(HttpStatus.SC_OK);
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
- return "";
- } , new JsonTransformer());
+ return "{}";
+ });
+ // http://ip_address:port/api/{userId}/sensors returns json objects of all sensors configured
+ get(HUE_CONTEXT + "/:userid/sensors", "application/json", (request, response) -> {
+ String userId = request.params(":userid");
+ log.debug("hue sensors list requested: " + userId + " from " + request.ip());
+ response.status(HttpStatus.SC_OK);
+ response.header("Access-Control-Allow-Origin", request.headers("Origin"));
+ return "{}";
+ });
+ // http://ip_address:port/api/{userId}/rules returns json objects of all rules configured
+ get(HUE_CONTEXT + "/:userid/rules", "application/json", (request, response) -> {
+ String userId = request.params(":userid");
+ log.debug("hue rules list requested: " + userId + " from " + request.ip());
+ response.status(HttpStatus.SC_OK);
+ response.header("Access-Control-Allow-Origin", request.headers("Origin"));
+ return "{}";
+ });
+ // http://ip_address:port/api/{userId}/resourcelinks returns json objects of all resourcelinks configured
+ get(HUE_CONTEXT + "/:userid/resourcelinks", "application/json", (request, response) -> {
+ String userId = request.params(":userid");
+ log.debug("hue resourcelinks list requested: " + userId + " from " + request.ip());
+ response.status(HttpStatus.SC_OK);
+ response.header("Access-Control-Allow-Origin", request.headers("Origin"));
+ return "{}";
+ });
get(HUE_CONTEXT + "/:userid/lights", "application/json", (request, response) -> {
String userId = request.params(":userid");
if(bridgeSettings.isTraceupnp())
@@ -203,7 +238,7 @@ public class HueMulator implements HueErrorStringSet {
aDeviceType = aNewUser.getDevicetype();
}
if(newUser == null)
- newUser = "lightssystem";
+ newUser = getNewUserID(request.ip());
if(aDeviceType == null)
aDeviceType = "";
@@ -241,7 +276,7 @@ public class HueMulator implements HueErrorStringSet {
aDeviceType = aNewUser.getDevicetype();
}
if(newUser == null)
- newUser = "lightssystem";
+ newUser = getNewUserID(request.ip());
if(aDeviceType == null)
aDeviceType = "";
@@ -252,20 +287,17 @@ public class HueMulator implements HueErrorStringSet {
return "[{\"success\":{\"username\":\"" + newUser + "\"}}]";
} );
- // http://ip_address:port/api/config returns json objects for the config when no user is given
+ // http://ip_address:port/api/config returns json objects for the public config when no user is given
get(HUE_CONTEXT + "/config", "application/json", (request, response) -> {
if(bridgeSettings.isTraceupnp())
log.info("Traceupnp: hue api/config config requested: from " + request.ip());
- log.debug("hue api config requested: from " + request.ip());
- HueApiResponse apiResponse = new HueApiResponse("Philips hue", bridgeSettings.getUpnpConfigAddress(), "My App", "none");
+ log.debug("hue api public config requested, from " + request.ip());
+ HuePublicConfig apiResponse = HuePublicConfig.createConfig("Philips hue", bridgeSettings.getUpnpConfigAddress());
response.type("application/json; charset=utf-8");
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
response.status(HttpStatus.SC_OK);
-// String responseString = null;
-// responseString = "[{\"swversion\":\"" + apiResponse.getConfig().getSwversion() + "\",\"apiversion\":\"" + apiResponse.getConfig().getApiversion() + "\",\"name\":\"" + apiResponse.getConfig().getName() + "\",\"mac\":\"" + apiResponse.getConfig().getMac() + "\"}]";
-// return responseString;
- return apiResponse.getConfig();
+ return apiResponse;
}, new JsonTransformer());
// http://ip_address:port/api/{userId}/config returns json objects for the config
@@ -274,7 +306,7 @@ public class HueMulator implements HueErrorStringSet {
if(bridgeSettings.isTraceupnp())
log.info("Traceupnp: hue api/:userid/config config requested: " + userId + " from " + request.ip());
log.debug("hue api config requested: " + userId + " from " + request.ip());
- HueApiResponse apiResponse = new HueApiResponse("Philips hue", bridgeSettings.getUpnpConfigAddress(), "My App", userId);
+ HueApiResponse apiResponse = new HueApiResponse("Philips hue", bridgeSettings.getUpnpConfigAddress(), bridgeSettings.getWhitelist());
response.type("application/json; charset=utf-8");
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
@@ -286,10 +318,17 @@ public class HueMulator implements HueErrorStringSet {
// http://ip_address:port/api/{userId} returns json objects for the full state
get(HUE_CONTEXT + "/:userid", "application/json", (request, response) -> {
String userId = request.params(":userid");
- log.debug("hue api full state requested: " + userId + " from " + request.ip());
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
- if(userId.equalsIgnoreCase("undefined"))
- return "[{\"error\":{\"address\":\"/\",\"description\":\"unauthorized user\",\"type\":\"1\"}}]";
+ response.type("application/json; charset=utf-8");
+ response.status(HttpStatus.SC_OK);
+ if(userId == null || userId.equalsIgnoreCase("undefined") || userId.equalsIgnoreCase("null") || userId.equalsIgnoreCase("")) {
+ log.debug("hue api full state requested: " + userId + " from " + request.ip() + ". No User supplied");
+ HueErrorResponse theErrorResp = new HueErrorResponse();
+ theErrorResp.addError(new HueError(new HueErrorDetails("1", "/api/" + userId, "unauthorized user", null, null, null)));
+ return theErrorResp.getTheErrors();
+ }
+ else
+ log.debug("hue api full state requested: " + userId + " from " + request.ip());
List descriptorList = repository.findAll();
if (descriptorList == null) {
response.status(HttpStatus.SC_NOT_FOUND);
@@ -302,11 +341,9 @@ public class HueMulator implements HueErrorStringSet {
deviceList.put(descriptor.getId(), deviceResponse);
}
);
- HueApiResponse apiResponse = new HueApiResponse("Philips hue", bridgeSettings.getUpnpConfigAddress(), "My App", userId);
+ HueApiResponse apiResponse = new HueApiResponse("Philips hue", bridgeSettings.getUpnpConfigAddress(), bridgeSettings.getWhitelist());
apiResponse.setLights(deviceList);
- response.type("application/json; charset=utf-8");
- response.status(HttpStatus.SC_OK);
return apiResponse;
}, new JsonTransformer());
@@ -315,18 +352,20 @@ public class HueMulator implements HueErrorStringSet {
String userId = request.params(":userid");
String lightId = request.params(":id");
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
+ response.type("application/json; charset=utf-8");
+ response.status(HttpStatus.SC_OK);
log.debug("hue light requested: " + lightId + " for user: " + userId + " from " + request.ip());
DeviceDescriptor device = repository.findOne(lightId);
if (device == null) {
response.status(HttpStatus.SC_NOT_FOUND);
- return "[{\"error\":{\"type\": 3, \"address\": \"/lights/" + lightId + "\",\"description\": \"Object not found\"}}]";
+ HueErrorResponse theErrorResp = new HueErrorResponse();
+ theErrorResp.addError(new HueError(new HueErrorDetails("3", "/api/" + userId + "/lights/" + lightId, "Object not found", null, null, null)));
+ return theErrorResp.getTheErrors();
} else {
log.debug("found device named: " + device.getName());
}
DeviceResponse lightResponse = DeviceResponse.createResponse(device);
- response.type("application/json; charset=utf-8");
- response.status(HttpStatus.SC_OK);
return lightResponse;
}, new JsonTransformer());
@@ -1025,6 +1064,19 @@ public class HueMulator implements HueErrorStringSet {
return responseString;
}
+ private String getNewUserID(String seed) {
+ UUID uid = UUID.fromString(seed);
+ StringTokenizer st = new StringTokenizer(uid.toString(), "-");
+ String newUser = "";
+ while(st.hasMoreTokens()) {
+ newUser = newUser + st.nextToken();
+ }
+
+ return newUser;
+ }
+ private String lookupWhitelistUser() {
+
+ }
@Override
public void setErrorString(String anError) {
errorString = anError;