Compare commits

..

20 Commits

Author SHA1 Message Date
Admin
e3f5946c9d Updated handling to be CORS compatible. 2015-11-13 11:40:13 -06:00
Admin
12eab16f21 updated Readme and enhance emulator logging code. 2015-11-13 11:26:19 -06:00
Admin
3df68047a9 Updated handling of dimming/brightness request. This could be buggy if
the echo changed to not send an on command when changing dimming. The
HUE state change API is not consistent for brightness handling.
2015-11-13 10:57:18 -06:00
Admin
0dd652f82a Updated device return for HUE emulation based on new information of LUX
bulb handling in the API from the Philips dev info.
2015-11-12 16:31:01 -06:00
Admin
53af1a4dfd Final tweaks to the order of sections in the readme 2015-11-11 15:24:17 -06:00
Admin
816a0025b1 Finished updating upnp for the readme 2015-11-11 15:16:42 -06:00
Admin
405562809a finished adding harmony items to readme 2015-11-11 14:39:13 -06:00
Admin
4c87c6fce8 Update readme some more. 2015-11-11 13:29:06 -06:00
Admin
2fd0f7748b Some more readme updates. 2015-11-11 13:19:50 -06:00
Admin
ed5f3b4b3c More readme updates. 2015-11-11 12:43:38 -06:00
Admin
aad09b7527 More updates to readme 2015-11-11 11:28:41 -06:00
Admin
0ae66da085 Continuation of readme updating. 2015-11-11 11:26:42 -06:00
Admin
d344b764da Updated HUE REst descriptions. 2015-11-10 16:48:30 -06:00
Admin
c85b67fb9f Next update for HUE API description 2015-11-10 16:25:16 -06:00
Admin
a23d662444 Adding supported HUE API calls descriptions. 2015-11-10 13:57:01 -06:00
Admin
4b98f799c2 Updated vera returns for scened and devices. 2015-11-10 11:51:21 -06:00
Admin
acba2b5cae Another config rest api clarification. 2015-11-10 11:45:40 -06:00
Admin
4dc818296a Updated Configuration REST API commands. 2015-11-10 11:40:41 -06:00
Admin
40123ed858 Updating document for REST usage. 2015-11-09 16:47:38 -06:00
Admin
718ba5a5c2 Updated build in pom.xml to include classes that were removed for
minimize. This required a dummy clas setup as well in the Harmony
Server.
2015-11-04 11:00:46 -06:00
8 changed files with 693 additions and 115 deletions

601
README.md

File diff suppressed because one or more lines are too long

30
pom.xml
View File

@@ -5,7 +5,7 @@
<groupId>com.bwssystems.HABridge</groupId> <groupId>com.bwssystems.HABridge</groupId>
<artifactId>ha-bridge</artifactId> <artifactId>ha-bridge</artifactId>
<version>1.0.6</version> <version>1.0.8</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>HA Bridge</name> <name>HA Bridge</name>
@@ -80,11 +80,6 @@
<artifactId>smack-core</artifactId> <artifactId>smack-core</artifactId>
<version>4.0.7</version> <version>4.0.7</version>
</dependency> </dependency>
<dependency>
<groupId>org.igniterealtime.smack</groupId>
<artifactId>smack-debug</artifactId>
<version>4.0.7</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
@@ -126,11 +121,12 @@
<exclude>META-INF/*.RSA</exclude> <exclude>META-INF/*.RSA</exclude>
<exclude>META-INF/*.txt</exclude> <exclude>META-INF/*.txt</exclude>
<exclude>META-INF/maven/**</exclude> <exclude>META-INF/maven/**</exclude>
<exclude>META-INF/services/**</exclude>
<exclude>META-INF/DEPENDENCIES</exclude>
<exclude>about_files/**</exclude> <exclude>about_files/**</exclude>
</excludes> </excludes>
</filter> </filter>
<filter>
<artifact>*:*</artifact>
</filter>
<filter> <filter>
<artifact>org.slf4j:*</artifact> <artifact>org.slf4j:*</artifact>
<includes> <includes>
@@ -143,6 +139,24 @@
<include>**</include> <include>**</include>
</includes> </includes>
</filter> </filter>
<filter>
<artifact>xpp3:xpp3</artifact>
<includes>
<include>**</include>
</includes>
</filter>
<filter>
<artifact>org.igniterealtime.smack:*</artifact>
<includes>
<include>**</include>
</includes>
</filter>
<filter>
<artifact>com.github.bwssytems:harmony-java-client</artifact>
<includes>
<include>**</include>
</includes>
</filter>
</filters> </filters>
<transformers> <transformers>
<transformer <transformer

View File

@@ -1,8 +1,5 @@
package com.bwssystems.HABridge.api.hue; package com.bwssystems.HABridge.api.hue;
import java.util.HashMap;
import java.util.Map;
/** /**
* Created by arm on 4/14/15. * Created by arm on 4/14/15.
*/ */
@@ -14,7 +11,6 @@ public class DeviceResponse {
private String manufacturername; private String manufacturername;
private String uniqueid; private String uniqueid;
private String swversion; private String swversion;
private Map<String, String> pointsymbol;
public DeviceState getState() { public DeviceState getState() {
return state; return state;
@@ -72,27 +68,6 @@ public class DeviceResponse {
this.swversion = swversion; this.swversion = swversion;
} }
public Map<String, String> getPointsymbol() {
if(pointsymbol == null)
{
pointsymbol = new HashMap<>();
pointsymbol.put("1", "none");
pointsymbol.put("2", "none");
pointsymbol.put("3", "none");
pointsymbol.put("4", "none");
pointsymbol.put("5", "none");
pointsymbol.put("6", "none");
pointsymbol.put("7", "none");
pointsymbol.put("8", "none");
}
return pointsymbol;
}
public void setPointsymbol(Map<String, String> pointsymbol) {
this.pointsymbol = pointsymbol;
}
public static DeviceResponse createResponse(String name, String id){ public static DeviceResponse createResponse(String name, String id){
DeviceState deviceState = new DeviceState(); DeviceState deviceState = new DeviceState();
DeviceResponse response = new DeviceResponse(); DeviceResponse response = new DeviceResponse();
@@ -102,14 +77,13 @@ public class DeviceResponse {
deviceState.setEffect("none"); deviceState.setEffect("none");
deviceState.setAlert("none"); deviceState.setAlert("none");
deviceState.setBri(254); deviceState.setBri(254);
deviceState.setSat(254);
response.setName(name); response.setName(name);
response.setUniqueid(id); response.setUniqueid(id);
response.setManufacturername("Philips"); response.setManufacturername("Philips");
response.setType("Dimmable light"); response.setType("Dimmable light");
response.setModelid("LWB004"); response.setModelid("LWB004");
response.setSwversion("65003148"); response.setSwversion("66012040");
return response; return response;
} }

View File

@@ -1,6 +1,5 @@
package com.bwssystems.HABridge.api.hue; package com.bwssystems.HABridge.api.hue;
import java.util.List;
/** /**
* Created by arm on 4/14/15. * Created by arm on 4/14/15.
@@ -8,14 +7,9 @@ import java.util.List;
public class DeviceState { public class DeviceState {
private boolean on; private boolean on;
private int bri = 255; private int bri = 255;
private int hue;
private int sat;
private String effect; private String effect;
private int ct;
private String alert; private String alert;
private String colormode;
private boolean reachable; private boolean reachable;
private List<Double> xy;
public boolean isOn() { public boolean isOn() {
return on; return on;
@@ -33,22 +27,6 @@ public class DeviceState {
this.bri = bri; this.bri = bri;
} }
public int getHue() {
return hue;
}
public void setHue(int hue) {
this.hue = hue;
}
public int getSat() {
return sat;
}
public void setSat(int sat) {
this.sat = sat;
}
public String getEffect() { public String getEffect() {
return effect; return effect;
} }
@@ -57,14 +35,6 @@ public class DeviceState {
this.effect = effect; this.effect = effect;
} }
public int getCt() {
return ct;
}
public void setCt(int ct) {
this.ct = ct;
}
public String getAlert() { public String getAlert() {
return alert; return alert;
} }
@@ -73,14 +43,6 @@ public class DeviceState {
this.alert = alert; this.alert = alert;
} }
public String getColormode() {
return colormode;
}
public void setColormode(String colormode) {
this.colormode = colormode;
}
public boolean isReachable() { public boolean isReachable() {
return reachable; return reachable;
} }
@@ -89,14 +51,6 @@ public class DeviceState {
this.reachable = reachable; this.reachable = reachable;
} }
public List<Double> getXy() {
return xy;
}
public void setXy(List<Double> xy) {
this.xy = xy;
}
@Override @Override
public String toString() { public String toString() {
return "DeviceState{" + return "DeviceState{" +

View File

@@ -1,6 +1,7 @@
package com.bwssystems.HABridge.devicemanagmeent; package com.bwssystems.HABridge.devicemanagmeent;
import static spark.Spark.get; import static spark.Spark.get;
import static spark.Spark.options;
import static spark.Spark.post; import static spark.Spark.post;
import static spark.Spark.put; import static spark.Spark.put;
import static spark.Spark.delete; import static spark.Spark.delete;
@@ -52,6 +53,15 @@ public class DeviceResource {
private void setupEndpoints() { private void setupEndpoints() {
log.info("HABridge device management service started.... "); log.info("HABridge device management service started.... ");
// http://ip_address:port/api/devices CORS request
options(API_CONTEXT, "application/json", (request, response) -> {
response.status(HttpStatus.SC_OK);
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
response.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
response.header("Access-Control-Allow-Headers", request.headers("Access-Control-Request-Headers"));
response.header("Content-Type", "text/html; charset=utf-8");
return "";
});
post(API_CONTEXT, "application/json", (request, response) -> { post(API_CONTEXT, "application/json", (request, response) -> {
log.debug("Create a Device - request body: " + request.body()); log.debug("Create a Device - request body: " + request.body());
DeviceDescriptor device = new Gson().fromJson(request.body(), DeviceDescriptor.class); DeviceDescriptor device = new Gson().fromJson(request.body(), DeviceDescriptor.class);
@@ -67,11 +77,21 @@ public class DeviceResource {
deviceRepository.save(device); deviceRepository.save(device);
log.debug("Created a Device: " + request.body()); log.debug("Created a Device: " + request.body());
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
response.status(HttpStatus.SC_CREATED); response.status(HttpStatus.SC_CREATED);
return device; return device;
}, new JsonTransformer()); }, new JsonTransformer());
// http://ip_address:port/api/devices/:id CORS request
options(API_CONTEXT + "/:id", "application/json", (request, response) -> {
response.status(HttpStatus.SC_OK);
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
response.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
response.header("Access-Control-Allow-Headers", request.headers("Access-Control-Request-Headers"));
response.header("Content-Type", "text/html; charset=utf-8");
return "";
});
put (API_CONTEXT + "/:id", "application/json", (request, response) -> { put (API_CONTEXT + "/:id", "application/json", (request, response) -> {
log.debug("Edit a Device - request body: " + request.body()); log.debug("Edit a Device - request body: " + request.body());
DeviceDescriptor device = new Gson().fromJson(request.body(), DeviceDescriptor.class); DeviceDescriptor device = new Gson().fromJson(request.body(), DeviceDescriptor.class);

View File

@@ -16,6 +16,7 @@ import com.google.gson.Gson;
import net.java.dev.eval.Expression; import net.java.dev.eval.Expression;
import static spark.Spark.get; import static spark.Spark.get;
import static spark.Spark.options;
import static spark.Spark.post; import static spark.Spark.post;
import static spark.Spark.put; import static spark.Spark.put;
@@ -85,6 +86,15 @@ public class HueMulator {
return deviceResponseMap; return deviceResponseMap;
} , new JsonTransformer()); } , new JsonTransformer());
// http://ip_address:port/api CORS request
options(HUE_CONTEXT, "application/json", (request, response) -> {
response.status(HttpStatus.SC_OK);
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
response.header("Access-Control-Allow-Methods", "GET, POST, PUT");
response.header("Access-Control-Allow-Headers", request.headers("Access-Control-Request-Headers"));
response.header("Content-Type", "text/html; charset=utf-8");
return "";
});
// http://ip_address:port/api with body of user request returns json object for a success of user add // http://ip_address:port/api with body of user request returns json object for a success of user add
post(HUE_CONTEXT, "application/json", (request, response) -> { post(HUE_CONTEXT, "application/json", (request, response) -> {
UserCreateRequest aNewUser = null; UserCreateRequest aNewUser = null;
@@ -105,11 +115,21 @@ public class HueMulator {
aDeviceType = "<not given>"; aDeviceType = "<not given>";
log.debug("hue api user create requested for device type: " + aDeviceType + " and username: " + newUser); log.debug("hue api user create requested for device type: " + aDeviceType + " and username: " + newUser);
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
response.type("application/json; charset=utf-8"); response.type("application/json; charset=utf-8");
response.status(HttpStatus.SC_OK); response.status(HttpStatus.SC_OK);
return "[{\"success\":{\"username\":\"" + newUser + "\"}}]"; return "[{\"success\":{\"username\":\"" + newUser + "\"}}]";
} ); } );
// http://ip_address:port/api/* CORS request
options(HUE_CONTEXT + "/*", "application/json", (request, response) -> {
response.status(HttpStatus.SC_OK);
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
response.header("Access-Control-Allow-Methods", "GET, POST, PUT");
response.header("Access-Control-Allow-Headers", request.headers("Access-Control-Request-Headers"));
response.header("Content-Type", "text/html; charset=utf-8");
return "";
});
// http://ip_address:port/api/* with body of user request returns json object for a success of user add - This method is for Harmony Hub // http://ip_address:port/api/* with body of user request returns json object for a success of user add - This method is for Harmony Hub
post(HUE_CONTEXT + "/*", "application/json", (request, response) -> { post(HUE_CONTEXT + "/*", "application/json", (request, response) -> {
UserCreateRequest aNewUser = null; UserCreateRequest aNewUser = null;
@@ -130,6 +150,7 @@ public class HueMulator {
aDeviceType = "<not given>"; aDeviceType = "<not given>";
log.debug("HH trace: hue api user create requested for device type: " + aDeviceType + " and username: " + newUser); log.debug("HH trace: hue api user create requested for device type: " + aDeviceType + " and username: " + newUser);
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
response.type("application/json; charset=utf-8"); response.type("application/json; charset=utf-8");
response.status(HttpStatus.SC_OK); response.status(HttpStatus.SC_OK);
return "[{\"success\":{\"username\":\"" + newUser + "\"}}]"; return "[{\"success\":{\"username\":\"" + newUser + "\"}}]";
@@ -178,6 +199,15 @@ public class HueMulator {
return lightResponse; return lightResponse;
}, new JsonTransformer()); }, new JsonTransformer());
// http://ip_address:port/api/:userid/lights/:id/state CORS request
options(HUE_CONTEXT + "/:userid/lights/:id/state", "application/json", (request, response) -> {
response.status(HttpStatus.SC_OK);
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
response.header("Access-Control-Allow-Methods", "GET, POST, PUT");
response.header("Access-Control-Allow-Headers", request.headers("Access-Control-Request-Headers"));
response.header("Content-Type", "text/html; charset=utf-8");
return "";
});
// http://ip_address:port/api/{userId}/lights/{lightId}/state uses json object to set the lights state // http://ip_address:port/api/{userId}/lights/{lightId}/state uses json object to set the lights state
put(HUE_CONTEXT + "/:userid/lights/:id/state", "application/json", (request, response) -> { put(HUE_CONTEXT + "/:userid/lights/:id/state", "application/json", (request, response) -> {
/** /**
@@ -204,23 +234,39 @@ public class HueMulator {
return null; return null;
} }
String responseString; String responseString =null;
String url; String url = null;
if (state.isOn()) { if (state.isOn()) {
responseString = "[{\"success\":{\"/lights/" + lightId + "/state/on\":true}}]"; responseString = "[{\"success\":{\"/lights/" + lightId + "/state/on\":true}}";
url = device.getOnUrl(); url = device.getOnUrl();
} else { } else if (request.body().contains("false")) {
responseString = "[{\"success\":{\"/lights/" + lightId + "/state/on\":false}}]"; responseString = "[{\"success\":{\"/lights/" + lightId + "/state/on\":false}}";
url = device.getOffUrl(); url = device.getOffUrl();
} }
if(device.getDeviceType().contains("activity")) if(request.body().contains("bri"))
{
if(url == null)
{
url = device.getOnUrl();
responseString = "[";
}
else
responseString = responseString + ",";
responseString = responseString + "{\"success\":{\"/lights/" + lightId + "/state/bri\":" + state.getBri() + "}}]";
}
else
responseString = responseString + "]";
if(device.getDeviceType().toLowerCase().contains("activity"))
{ {
log.debug("executing activity to Harmony: " + url); log.debug("executing activity to Harmony: " + url);
RunActivity anActivity = new Gson().fromJson(url, RunActivity.class); RunActivity anActivity = new Gson().fromJson(url, RunActivity.class);
myHarmony.startActivity(anActivity); myHarmony.startActivity(anActivity);
} }
else if(device.getDeviceType().contains("button")) else if(device.getDeviceType().toLowerCase().contains("button"))
{ {
log.debug("executing button press to Harmony: " + url); log.debug("executing button press to Harmony: " + url);
ButtonPress aDeviceButton = new Gson().fromJson(url, ButtonPress.class); ButtonPress aDeviceButton = new Gson().fromJson(url, ButtonPress.class);
@@ -228,7 +274,7 @@ public class HueMulator {
} }
else else
{ {
log.debug("executing activity to Http: " + url); log.debug("executing activity to Http " + (device.getHttpVerb() == null?"GET":device.getHttpVerb()) + ": " + url);
// quick template // quick template
String body; String body;
url = replaceIntensityValue(url, state.getBri()); url = replaceIntensityValue(url, state.getBri());
@@ -244,6 +290,7 @@ public class HueMulator {
} }
} }
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
response.type("application/json; charset=utf-8"); response.type("application/json; charset=utf-8");
response.status(HttpStatus.SC_OK); response.status(HttpStatus.SC_OK);
return responseString; return responseString;
@@ -309,7 +356,7 @@ public class HueMulator {
try { try {
HttpResponse response = httpClient.execute(request); HttpResponse response = httpClient.execute(request);
EntityUtils.consume(response.getEntity()); //close out inputstream ignore content EntityUtils.consume(response.getEntity()); //close out inputstream ignore content
log.debug("Execute on URL responded: " + response.getStatusLine().getStatusCode()); log.debug((httpVerb == null?"GET":httpVerb) + " execute on URL responded: " + response.getStatusLine().getStatusCode());
if(response.getStatusLine().getStatusCode() == 200){ if(response.getStatusLine().getStatusCode() == 200){
return true; return true;
} }

View File

@@ -15,6 +15,7 @@ import net.whistlingfish.harmony.ActivityChangeListener;
import net.whistlingfish.harmony.HarmonyClient; import net.whistlingfish.harmony.HarmonyClient;
import net.whistlingfish.harmony.HarmonyClientModule; import net.whistlingfish.harmony.HarmonyClientModule;
import net.whistlingfish.harmony.config.Activity; import net.whistlingfish.harmony.config.Activity;
import net.whistlingfish.harmony.protocol.OAReplyProvider;
public class HarmonyServer { public class HarmonyServer {
@Inject @Inject
@@ -22,12 +23,14 @@ public class HarmonyServer {
private HarmonyHandler myHarmony; private HarmonyHandler myHarmony;
private DevModeResponse devResponse; private DevModeResponse devResponse;
private OAReplyProvider dummyProvider;
private Logger log = LoggerFactory.getLogger(HarmonyServer.class); private Logger log = LoggerFactory.getLogger(HarmonyServer.class);
public HarmonyServer() { public HarmonyServer() {
super(); super();
myHarmony = null; myHarmony = null;
dummyProvider = null;
} }
public static HarmonyServer setup(BridgeSettings bridgeSettings) throws Exception { public static HarmonyServer setup(BridgeSettings bridgeSettings) throws Exception {
@@ -47,6 +50,8 @@ public class HarmonyServer {
private void execute(BridgeSettings mySettings) throws Exception { private void execute(BridgeSettings mySettings) throws Exception {
Boolean noopCalls = Boolean.parseBoolean(System.getProperty("noop.calls", "false")); Boolean noopCalls = Boolean.parseBoolean(System.getProperty("noop.calls", "false"));
String modeString = ""; String modeString = "";
if(dummyProvider != null)
log.debug("something is very wrong as dummyProvider is not null...");
if(mySettings.isDevMode()) if(mySettings.isDevMode())
modeString = " (development mode)"; modeString = " (development mode)";
if(noopCalls) if(noopCalls)

View File

@@ -103,8 +103,7 @@ app.service('bridgeService', function ($http, $window, BridgeSettings) {
if (error.data) { if (error.data) {
self.state.error = error.data.message; self.state.error = error.data.message;
} else { } else {
self.state.error = "If you're not seeing any devices, you may be running into problems with CORS. " + self.state.error = "Some error occurred.";
"You can work around this by running a fresh launch of Chrome with the --disable-web-security flag.";
} }
console.log(error); console.log(error);
} }