First Beta of Harmony configuration for testing.

This commit is contained in:
Admin
2015-10-27 16:39:13 -05:00
parent 295b1e1a30
commit b443d16a11
10 changed files with 261 additions and 39 deletions

22
pom.xml
View File

@@ -17,7 +17,19 @@
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.github.bwssytems</groupId>
<artifactId>harmony-java-client</artifactId>
<version>1.0.4</version>
</dependency>
<dependency>
<groupId>com.sparkjava</groupId>
<artifactId>spark-core</artifactId>
@@ -58,6 +70,16 @@
<artifactId>eval</artifactId>
<version>0.5</version>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>4.0-beta4</version>
</dependency>
<dependency>
<groupId>org.igniterealtime.smack</groupId>
<artifactId>smack-core</artifactId>
<version>4.0.2</version>
</dependency>
</dependencies>
<build>

View File

@@ -90,6 +90,10 @@ public class BridgeSettings {
public Boolean isValidHarmony() {
if(this.harmonyaddress.contains(Configuration.DEFAULT_HARMONY_ADDRESS))
return false;
if(this.harmonypwd == null || this.harmonypwd == "")
return false;
if(this.harmonyuser == null || this.harmonyuser == "")
return false;
return true;
}
}

View File

@@ -12,6 +12,7 @@ import com.bwssystems.HABridge.devicemanagmeent.*;
import com.bwssystems.HABridge.hue.HueMulator;
import com.bwssystems.HABridge.upnp.UpnpListener;
import com.bwssystems.HABridge.upnp.UpnpSettingsResource;
import com.bwssystems.harmony.HarmonyServer;
public class HABridge {
@@ -33,6 +34,7 @@ public class HABridge {
public static void main(String[] args) {
Logger log = LoggerFactory.getLogger(HABridge.class);
DeviceResource theResources;
HarmonyServer myHarmonyServer;
HueMulator theHueMulator;
UpnpSettingsResource theSettingResponder;
UpnpListener theUpnpListener;
@@ -69,10 +71,17 @@ public class HABridge {
port(Integer.valueOf(bridgeSettings.getServerPort()));
// sparkjava config directive to set html static file location for Jetty
staticFileLocation("/public");
//setup the harmony connection if available
try {
myHarmonyServer = HarmonyServer.setup(bridgeSettings);
} catch (Exception e) {
log.error("Cannot get harmony client setup, Exiting with message: " + e.getMessage(), e);
return;
}
// setup the class to handle the resource setup rest api
theResources = new DeviceResource(bridgeSettings);
theResources = new DeviceResource(bridgeSettings, myHarmonyServer.getMyHarmony());
// setup the class to handle the hue emulator rest api
theHueMulator = new HueMulator(theResources.getDeviceRepository());
theHueMulator = new HueMulator(theResources.getDeviceRepository(), myHarmonyServer.getMyHarmony());
theHueMulator.setupServer();
// setup the class to handle the upnp response rest api
theSettingResponder = new UpnpSettingsResource(bridgeSettings);

View File

@@ -18,6 +18,7 @@ import com.bwssystems.HABridge.BridgeSettings;
import com.bwssystems.HABridge.JsonTransformer;
import com.bwssystems.HABridge.dao.DeviceDescriptor;
import com.bwssystems.HABridge.dao.DeviceRepository;
import com.bwssystems.harmony.HarmonyHandler;
import com.bwssystems.luupRequests.Sdata;
import com.bwssystems.vera.VeraInfo;
import com.google.gson.Gson;
@@ -31,12 +32,14 @@ public class DeviceResource {
private DeviceRepository deviceRepository;
private VeraInfo veraInfo;
private HarmonyHandler myHarmonyHandler;
private static final Set<String> supportedVerbs = new HashSet<>(Arrays.asList("get", "put", "post"));
public DeviceResource(BridgeSettings theSettings) {
public DeviceResource(BridgeSettings theSettings, HarmonyHandler myHarmony) {
super();
deviceRepository = new DeviceRepository(theSettings.getUpnpDeviceDb());
veraInfo = new VeraInfo(theSettings.getVeraAddress(), theSettings.isValidVera());
myHarmonyHandler = myHarmony;
setupEndpoints();
}
@@ -150,5 +153,13 @@ public class DeviceResource {
return sData.getScenes();
}, new JsonTransformer());
get (API_CONTEXT + "/harmony/activities", "application/json", (request, response) -> {
log.debug("Get harmony activities");
response.status(HttpStatus.SC_OK);
if(myHarmonyHandler != null)
return myHarmonyHandler.getActivities();
return "";
}, new JsonTransformer());
}
}

View File

@@ -6,6 +6,7 @@ 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.dao.*;
import com.bwssystems.harmony.HarmonyHandler;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
@@ -51,15 +52,17 @@ public class HueMulator {
private static final String HUE_CONTEXT = "/api";
private DeviceRepository repository;
private HarmonyHandler myHarmony;
private HttpClient httpClient;
private ObjectMapper mapper;
public HueMulator(DeviceRepository aDeviceRepository){
public HueMulator(DeviceRepository aDeviceRepository, HarmonyHandler theHandler){
httpClient = HttpClients.createDefault();
mapper = new ObjectMapper(); //armzilla: work around Echo incorrect content type and breaking mapping. Map manually
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
repository = aDeviceRepository;
myHarmony = theHandler;
}
// This function sets up the sparkjava rest calls for the hue api
@@ -209,6 +212,14 @@ public class HueMulator {
url = device.getOffUrl();
}
if(device.getDeviceType() == "activity")
{
log.debug("executing activity to Harmony: " + url);
myHarmony.startActivity(url);
}
else
{
log.debug("executing activity to Http: " + url);
// quick template
String body;
url = replaceIntensityValue(url, state.getBri());
@@ -222,6 +233,7 @@ public class HueMulator {
log.error("Error on calling url to change device state: " + url);
return null;
}
}
response.type("application/json; charset=utf-8");
response.status(HttpStatus.SC_OK);

View File

@@ -1,5 +0,0 @@
package com.bwssystems.harmony;
public class HarmonyActivities {
}

View File

@@ -0,0 +1,89 @@
package com.bwssystems.harmony;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.whistlingfish.harmony.HarmonyClient;
import net.whistlingfish.harmony.config.Activity;
import net.whistlingfish.harmony.config.Device;
import net.whistlingfish.harmony.config.HarmonyConfig;
public class HarmonyHandler {
private static final Logger log = LoggerFactory.getLogger(HarmonyHandler.class);
private HarmonyClient harmonyClient;
private Boolean noopCalls;
public HarmonyHandler(HarmonyClient theClient, Boolean noopCallsSetting) {
super();
noopCalls = noopCallsSetting;
harmonyClient = theClient;
}
public List<Activity> getActivities() {
log.debug("Harmony api activities list requested.");
return harmonyClient.getConfig().getActivities();
}
public List<Device> getDevices() {
log.debug("Harmony api device list requested.");
return harmonyClient.getConfig().getDevices();
}
public HarmonyConfig getConfig() {
log.debug("Harmony api config requested.");
return harmonyClient.getConfig();
}
public Activity getCurrentActivity() {
log.debug("Harmony api current sctivity requested.");
return harmonyClient.getCurrentActivity();
}
public Boolean startActivity(String anActivity) {
log.debug("Harmony api start activity requested for: " + anActivity + " noop mode: " + noopCalls);
if (anActivity != null && !anActivity.isEmpty()) {
try {
if (!noopCalls)
harmonyClient.startActivity(Integer.parseInt(anActivity));
} catch (IllegalArgumentException e) {
try {
if (!noopCalls)
harmonyClient.startActivityByName(anActivity);
} catch (IllegalArgumentException ei) {
log.error("Error in finding activity: " + anActivity);
return false;
}
}
} else {
log.error("Error in finding activity: " + anActivity);
return false;
}
return true;
}
public Boolean pressButton(String aDevice, String aDeviceButton) {
log.debug("Harmony api press a button requested for device: " + aDevice + " and a for button: " + aDeviceButton + " noop mode: " + noopCalls);
if (aDeviceButton != null && !aDeviceButton.isEmpty()) {
try {
if (!noopCalls)
harmonyClient.pressButton(Integer.parseInt(aDevice), aDeviceButton);
} catch (IllegalArgumentException e) {
try {
if (!noopCalls)
harmonyClient.pressButton(aDevice, aDeviceButton);
} catch (IllegalArgumentException ei) {
log.error("Error in finding device: " + aDevice +" and a button: " + aDeviceButton);
return false;
}
}
} else {
log.error("Error in finding device: " + aDevice +" and a button: " + aDeviceButton);
return false;
}
return true;
}
}

View File

@@ -0,0 +1,60 @@
package com.bwssystems.harmony;
import static java.lang.String.format;
import javax.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.bwssystems.HABridge.BridgeSettings;
import com.google.inject.Guice;
import com.google.inject.Injector;
import net.whistlingfish.harmony.ActivityChangeListener;
import net.whistlingfish.harmony.HarmonyClient;
import net.whistlingfish.harmony.HarmonyClientModule;
import net.whistlingfish.harmony.config.Activity;
public class HarmonyServer {
@Inject
private HarmonyClient harmonyClient;
private HarmonyHandler myHarmony;
private Logger log = LoggerFactory.getLogger(HarmonyServer.class);
public HarmonyServer() {
super();
myHarmony = null;
}
public static HarmonyServer setup(BridgeSettings bridgeSettings) throws Exception {
if(!bridgeSettings.isValidHarmony()) {
return new HarmonyServer();
}
Injector injector = null;
injector = Guice.createInjector(new HarmonyClientModule());
HarmonyServer mainObject = new HarmonyServer();
injector.injectMembers(mainObject);
mainObject.execute(bridgeSettings);
return mainObject;
}
private void execute(BridgeSettings mySettings) throws Exception {
log.debug("setup initiated....");
harmonyClient.addListener(new ActivityChangeListener() {
@Override
public void activityStarted(Activity activity) {
log.info(format("activity changed: [%d] %s", activity.getId(), activity.getLabel()));
}
});
harmonyClient.connect(mySettings.getHarmonyAddress(), mySettings.getHarmonyUser(), mySettings.getHarmonyPwd());
Boolean noopCalls = Boolean.parseBoolean(System.getProperty("noop.calls", "false"));
myHarmony = new HarmonyHandler(harmonyClient, noopCalls);
}
public HarmonyHandler getMyHarmony() {
return myHarmony;
}
}

View File

@@ -149,15 +149,15 @@ app.service('bridgeService', function ($http, $window, BridgeSettings) {
this.updateShowHarmony = function () {
if(self.BridgeSettings.harmonyaddress == "1.1.1.1" || self.BridgeSettings.harmonyaddress == "")
self.state.showHarmony = false;
this.state.showHarmony = false;
else
self.state.showHarmony = true;
this.state.showHarmony = true;
return;
}
this.viewVeraDevices = function () {
this.state.error = "";
if(BridgeSettings.veraaddress == "1.1.1.1" || BridgeSettings.veraaddress == "")
if(!this.state.showVera)
return;
this.state.error = "";
return $http.get(this.state.base + "/vera/devices").then(
@@ -176,7 +176,7 @@ app.service('bridgeService', function ($http, $window, BridgeSettings) {
this.viewVeraScenes = function () {
this.state.error = "";
if(BridgeSettings.veraaddress == "1.1.1.1" || BridgeSettings.veraaddress == "")
if(!this.state.showVera)
return;
return $http.get(this.state.base + "/vera/scenes").then(
function (response) {
@@ -192,8 +192,28 @@ app.service('bridgeService', function ($http, $window, BridgeSettings) {
);
};
this.viewHarmonyActivities = function () {
this.state.error = "";
if(!this.state.showHarmony)
return;
return $http.get(this.state.base + "/harmony/activities").then(
function (response) {
self.state.harmonyactivities = response.data;
},
function (error) {
if (error.data) {
$window.alert("Get Harmony Activities Error: " + error.data.message);
} else {
$window.alert("Get Harmony Activities Error: unknown");
}
}
);
};
this.addDevice = function (id, name, type, onUrl, offUrl, httpVerb, contentType, contentBody, contentBodyOff) {
this.state.error = "";
if(httpVerb != null && httpVerb != "")
type = "custom";
if (id) {
var putUrl = this.state.base + "/" + id;
return $http.put(putUrl, {
@@ -220,6 +240,8 @@ app.service('bridgeService', function ($http, $window, BridgeSettings) {
} else {
if(type == null || type == "")
type = "switch";
if(httpVerb != null && httpVerb != "")
type = "custom";
return $http.post(this.state.base, {
name: name,
deviceType: type,
@@ -280,6 +302,8 @@ app.controller('ViewingController', function ($scope, $location, $http, $window,
bridgeService.deleteDevice(device.id);
};
$scope.testUrl = function (device, type) {
if(device.deviceType == "activity")
return;
if(type == "on") {
if(device.httpVerb == "PUT")
$http.put(device.onUrl, device.contentBody).then(
@@ -343,6 +367,7 @@ app.controller('AddingController', function ($scope, $location, $http, bridgeSer
bridgeService.device = $scope.device;
bridgeService.viewVeraDevices();
bridgeService.viewVeraScenes();
bridgeService.viewHarmonyActivities();
$scope.bridge = bridgeService.state;
bridgeService.updateShowVera();
bridgeService.updateShowHarmony();
@@ -423,20 +448,15 @@ app.controller('AddingController', function ($scope, $location, $http, bridgeSer
};
$scope.buildActivityUrls = function (harmonyactivity) {
if ($scope.vera.base.indexOf("http") < 0) {
$scope.vera.base = "http://" + $scope.vera.base;
}
$scope.device.deviceType = "scene";
$scope.device.name = verascene.name;
$scope.device.onUrl = $scope.vera.base + ":" + $scope.vera.port
+ "/data_request?id=action&output_format=json&serviceId=urn:micasaverde-com:serviceId:HomeAutomationGateway1&action=RunScene&SceneNum="
+ verascene.id;
$scope.device.offUrl = $scope.vera.base + ":" + $scope.vera.port
+ "/data_request?id=action&output_format=json&serviceId=urn:micasaverde-com:serviceId:HomeAutomationGateway1&action=RunScene&SceneNum="
+ verascene.id;
$scope.device.deviceType = "activity";
$scope.device.name = harmonyactivity.label;
$scope.device.onUrl = harmonyactivity.id;
$scope.device.offUrl = "-1";
};
$scope.testUrl = function (url) {
$scope.testUrl = function (device, type) {
if(device.deviceType == "activity")
return;
if(type == "on") {
if(device.httpVerb == "PUT")
$http.put(device.onUrl, device.contentBody).then(

View File

@@ -29,8 +29,8 @@
<th>Actions</th>
</tr>
</thead>
<tr ng-repeat="harmonyactivitye in bridge.harmonyactivities | orderBy:predicate:reverse">
<td>{{harmonyactivity.name}}</td>
<tr ng-repeat="harmonyactivity in bridge.harmonyactivities | orderBy:predicate:reverse">
<td>{{harmonyactivity.label}}</td>
<td>{{harmonyactivity.id}}</td>
<td>
<button class="btn btn-success" type="submit"