Compare commits

...

21 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
Admin
2e6944d840 Missed new java class in release. 2015-11-03 15:26:56 -06:00
9 changed files with 743 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>
<artifactId>ha-bridge</artifactId>
<version>1.0.5</version>
<version>1.0.8</version>
<packaging>jar</packaging>
<name>HA Bridge</name>
@@ -80,11 +80,6 @@
<artifactId>smack-core</artifactId>
<version>4.0.7</version>
</dependency>
<dependency>
<groupId>org.igniterealtime.smack</groupId>
<artifactId>smack-debug</artifactId>
<version>4.0.7</version>
</dependency>
</dependencies>
<build>
@@ -126,11 +121,12 @@
<exclude>META-INF/*.RSA</exclude>
<exclude>META-INF/*.txt</exclude>
<exclude>META-INF/maven/**</exclude>
<exclude>META-INF/services/**</exclude>
<exclude>META-INF/DEPENDENCIES</exclude>
<exclude>about_files/**</exclude>
</excludes>
</filter>
<filter>
<artifact>*:*</artifact>
</filter>
<filter>
<artifact>org.slf4j:*</artifact>
<includes>
@@ -143,6 +139,24 @@
<include>**</include>
</includes>
</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>
<transformers>
<transformer

View File

@@ -0,0 +1,50 @@
package com.bwssystems.HABridge;
import java.io.InputStream;
import java.util.Properties;
public final class Version {
private String version;
private String groupId;
private String artifactId;
private Properties prop;
public Version()
{
InputStream resourceAsStream =
(InputStream) this.getClass().getResourceAsStream(
"/version.properties"
);
this.prop = new Properties();
try
{
this.prop.load( resourceAsStream );
this.version = this.prop.getProperty("version");
this.groupId = this.prop.getProperty("groupId");
this.artifactId = this.prop.getProperty("artifactId");
}
catch (Exception e)
{
this.version = "0.0.0";
this.groupId = "no group";
this.artifactId = "no artifact";
}
}
public String getVersion() {
return version;
}
public String getGroupId() {
return groupId;
}
public String getArtifactId() {
return artifactId;
}
}

View File

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

View File

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

View File

@@ -1,6 +1,7 @@
package com.bwssystems.HABridge.devicemanagmeent;
import static spark.Spark.get;
import static spark.Spark.options;
import static spark.Spark.post;
import static spark.Spark.put;
import static spark.Spark.delete;
@@ -52,6 +53,15 @@ public class DeviceResource {
private void setupEndpoints() {
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) -> {
log.debug("Create a Device - request body: " + request.body());
DeviceDescriptor device = new Gson().fromJson(request.body(), DeviceDescriptor.class);
@@ -67,11 +77,21 @@ public class DeviceResource {
deviceRepository.save(device);
log.debug("Created a Device: " + request.body());
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
response.status(HttpStatus.SC_CREATED);
return device;
}, 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) -> {
log.debug("Edit a Device - request body: " + request.body());
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 static spark.Spark.get;
import static spark.Spark.options;
import static spark.Spark.post;
import static spark.Spark.put;
@@ -70,7 +71,7 @@ public class HueMulator {
// This function sets up the sparkjava rest calls for the hue api
public void setupServer() {
log.info("Hue emulator service started....");
// http://ip_address:port/api/{userId}/lights returns json objects of all lights configured
// http://ip_address:port/api/{userId}/lights returns json objects of all lights configured
get(HUE_CONTEXT + "/:userid/lights", "application/json", (request, response) -> {
String userId = request.params(":userid");
log.debug("hue lights list requested: " + userId + " from " + request.ip());
@@ -85,7 +86,16 @@ public class HueMulator {
return deviceResponseMap;
} , new JsonTransformer());
// http://ip_address:port/api with body of user request returns json object for a success of user add
// 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
post(HUE_CONTEXT, "application/json", (request, response) -> {
UserCreateRequest aNewUser = null;
String newUser = null;
@@ -105,11 +115,21 @@ public class HueMulator {
aDeviceType = "<not given>";
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.status(HttpStatus.SC_OK);
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
post(HUE_CONTEXT + "/*", "application/json", (request, response) -> {
UserCreateRequest aNewUser = null;
@@ -130,12 +150,13 @@ public class HueMulator {
aDeviceType = "<not given>";
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.status(HttpStatus.SC_OK);
return "[{\"success\":{\"username\":\"" + newUser + "\"}}]";
} );
// http://ip_address:port/api/{userId} returns json objects for the full state
// 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());
@@ -159,7 +180,7 @@ public class HueMulator {
return apiResponse;
}, new JsonTransformer());
// http://ip_address:port/api/{userId}/lights/{lightId} returns json object for a given light
// http://ip_address:port/api/{userId}/lights/{lightId} returns json object for a given light
get(HUE_CONTEXT + "/:userid/lights/:id", "application/json", (request, response) -> {
String userId = request.params(":userid");
String lightId = request.params(":id");
@@ -178,7 +199,16 @@ public class HueMulator {
return lightResponse;
}, new JsonTransformer());
// http://ip_address:port/api/{userId}/lights/{lightId}/state uses json object to set the lights state
// 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
put(HUE_CONTEXT + "/:userid/lights/:id/state", "application/json", (request, response) -> {
/**
* strangely enough the Echo sends a content type of application/x-www-form-urlencoded even though
@@ -204,23 +234,39 @@ public class HueMulator {
return null;
}
String responseString;
String url;
String responseString =null;
String url = null;
if (state.isOn()) {
responseString = "[{\"success\":{\"/lights/" + lightId + "/state/on\":true}}]";
responseString = "[{\"success\":{\"/lights/" + lightId + "/state/on\":true}}";
url = device.getOnUrl();
} else {
responseString = "[{\"success\":{\"/lights/" + lightId + "/state/on\":false}}]";
} else if (request.body().contains("false")) {
responseString = "[{\"success\":{\"/lights/" + lightId + "/state/on\":false}}";
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);
RunActivity anActivity = new Gson().fromJson(url, RunActivity.class);
myHarmony.startActivity(anActivity);
}
else if(device.getDeviceType().contains("button"))
else if(device.getDeviceType().toLowerCase().contains("button"))
{
log.debug("executing button press to Harmony: " + url);
ButtonPress aDeviceButton = new Gson().fromJson(url, ButtonPress.class);
@@ -228,7 +274,7 @@ public class HueMulator {
}
else
{
log.debug("executing activity to Http: " + url);
log.debug("executing activity to Http " + (device.getHttpVerb() == null?"GET":device.getHttpVerb()) + ": " + url);
// quick template
String body;
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.status(HttpStatus.SC_OK);
return responseString;
@@ -309,7 +356,7 @@ public class HueMulator {
try {
HttpResponse response = httpClient.execute(request);
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){
return true;
}

View File

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

View File

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