continuation of HueMulator refactor

This commit is contained in:
bwssystems
2016-12-24 12:09:50 -06:00
parent 40a9eb95ac
commit ca6b1ae32d
9 changed files with 300 additions and 197 deletions

View File

@@ -5,7 +5,7 @@
<groupId>com.bwssystems.HABridge</groupId>
<artifactId>ha-bridge</artifactId>
<version>3.5.1m</version>
<version>3.5.1n</version>
<packaging>jar</packaging>
<name>HA Bridge</name>

View File

@@ -58,11 +58,11 @@ public class HomeManager {
resourceList.put(DeviceMapTypes.HASS_DEVICE[DeviceMapTypes.resourceIndex], aHome);
homeList.put(DeviceMapTypes.HASS_DEVICE[DeviceMapTypes.typeIndex], aHome);
//setup the command execution Home
aHome = new CommandHome().createHome(bridgeSettings);
aHome = new CommandHome(bridgeSettings);
homeList.put(DeviceMapTypes.EXEC_DEVICE[DeviceMapTypes.typeIndex], aHome);
homeList.put(DeviceMapTypes.CMD_DEVICE[DeviceMapTypes.typeIndex], aHome);
//setup the http handler Home
aHome = new HTTPHome().createHome(bridgeSettings);
aHome = new HTTPHome(bridgeSettings);
homeList.put(DeviceMapTypes.HTTP_DEVICE[DeviceMapTypes.typeIndex], aHome);
homeList.put(DeviceMapTypes.CUSTOM_DEVICE[DeviceMapTypes.typeIndex], aHome);
homeList.put(DeviceMapTypes.VERA_DEVICE[DeviceMapTypes.typeIndex], aHome);

View File

@@ -8,6 +8,10 @@ public class CallItem {
private Integer delay;
private String type;
private String filterIPs;
private String httpVerb;
private String httpBody;
private String httpHeaders;
private String contentType;
public String getType() {
return type;
@@ -48,4 +52,36 @@ public class CallItem {
public void setDelay(Integer delay) {
this.delay = delay;
}
public String getHttpVerb() {
return httpVerb;
}
public void setHttpVerb(String httpVerb) {
this.httpVerb = httpVerb;
}
public String getHttpBody() {
return httpBody;
}
public void setHttpBody(String httpBody) {
this.httpBody = httpBody;
}
public String getHttpHeaders() {
return httpHeaders;
}
public void setHttpHeaders(String httpHeaders) {
this.httpHeaders = httpHeaders;
}
public String getContentType() {
return contentType;
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
}

View File

@@ -1225,31 +1225,7 @@ public class HueMulator {
} else if (callItems[i].getType() != null && callItems[i].getType().trim().equalsIgnoreCase(DeviceMapTypes.HASS_DEVICE[DeviceMapTypes.typeIndex])) {
responseString = homeManager.findHome(DeviceMapTypes.HASS_DEVICE[DeviceMapTypes.typeIndex]).deviceHandler(callItems[i], aMultiUtil, lightId, i, state, theStateChanges, stateHasBri, stateHasBriInc);
} else if (callItems[i].getType() != null && callItems[i].getType().trim().equalsIgnoreCase(DeviceMapTypes.EXEC_DEVICE[DeviceMapTypes.typeIndex])) {
log.debug("Exec Request called with url: " + url);
String intermediate;
if (callItems[i].getItem().getAsString().contains("exec://"))
intermediate = callItems[i].getItem().getAsString().substring(callItems[i].getItem().getAsString().indexOf("://") + 3);
else
intermediate = callItems[i].getItem().getAsString();
for (int x = 0; x < aMultiUtil.getSetCount(); x++) {
if (x > 0 || i > 0) {
try {
Thread.sleep(aMultiUtil.getTheDelay());
} catch (InterruptedException e) {
// ignore
}
}
if (callItems[i].getDelay() != null && callItems[i].getDelay() > 0)
aMultiUtil.setTheDelay(callItems[i].getDelay());
else
aMultiUtil.setTheDelay(bridgeSettings.getButtonsleep());
String anError = doExecRequest(intermediate,
BrightnessDecode.calculateIntensity(state, theStateChanges, stateHasBri, stateHasBriInc), lightId);
if (anError != null) {
responseString = anError;
x = aMultiUtil.getSetCount();
}
}
responseString = homeManager.findHome(DeviceMapTypes.EXEC_DEVICE[DeviceMapTypes.typeIndex]).deviceHandler(callItems[i], aMultiUtil, lightId, i, state, theStateChanges, stateHasBri, stateHasBriInc);
} else // This section allows the usage of http/tcp/udp/exec
// calls in a given set of items
{

View File

@@ -1,40 +1,96 @@
package com.bwssystems.exec;
import java.io.IOException;
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.api.hue.DeviceState;
import com.bwssystems.HABridge.api.hue.StateChangeBody;
import com.bwssystems.HABridge.hue.BrightnessDecode;
import com.bwssystems.HABridge.hue.MultiCommandUtil;
public class CommandHome implements Home {
private static final Logger log = LoggerFactory.getLogger(CommandHome.class);
public CommandHome() {
// TODO Auto-generated constructor stub
public CommandHome(BridgeSettingsDescriptor bridgeSettings) {
super();
createHome(bridgeSettings);
}
@Override
public String deviceHandler(CallItem anItem, MultiCommandUtil aMultiUtil, String lightId, int iterationCount,
DeviceState state, StateChangeBody theStateChanges, boolean stateHasBri, boolean stateHasBriInc) {
// TODO Auto-generated method stub
return null;
log.debug("Exec Request called with url: " + anItem.getItem().toString());
String responseString = null;
String intermediate;
if (anItem.getItem().toString().contains("exec://"))
intermediate = anItem.getItem().toString().substring(anItem.getItem().toString().indexOf("://") + 3);
else
intermediate = anItem.getItem().toString();
for (int x = 0; x < aMultiUtil.getSetCount(); x++) {
if (x > 0 || iterationCount > 0) {
try {
Thread.sleep(aMultiUtil.getTheDelay());
} catch (InterruptedException e) {
// ignore
}
}
if (anItem.getDelay() != null && anItem.getDelay() > 0)
aMultiUtil.setTheDelay(anItem.getDelay());
else
aMultiUtil.setTheDelay(aMultiUtil.getDelayDefault());
String anError = doExecRequest(intermediate,
BrightnessDecode.calculateIntensity(state, theStateChanges, stateHasBri, stateHasBriInc), lightId);
if (anError != null) {
responseString = anError;
x = aMultiUtil.getSetCount();
}
}
return responseString;
}
private String doExecRequest(String anItem, int intensity, String lightId) {
log.debug("Executing request: " + anItem);
String responseString = null;
if (anItem != null && !anItem.equalsIgnoreCase("")) {
try {
Process p = Runtime.getRuntime().exec(BrightnessDecode.replaceIntensityValue(anItem, intensity, false));
log.debug("Process running: " + p.isAlive());
} catch (IOException e) {
log.warn("Could not execute request: " + anItem, e);
responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
+ "\",\"description\": \"Error on calling out to device\", \"parameter\": \"/lights/" + lightId
+ "state\"}}]";
}
} else {
log.warn("Could not execute request. Request is empty.");
responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
+ "\",\"description\": \"Error on calling out to device\", \"parameter\": \"/lights/" + lightId
+ "state\"}}]";
}
return responseString;
}
@Override
public Home createHome(BridgeSettingsDescriptor bridgeSettings) {
// TODO Auto-generated method stub
return null;
// noop
return this;
}
@Override
public Object getItems(String type) {
// Not a resource
// noop
return null;
}
@Override
public void closeHome() {
// TODO Auto-generated method stub
// noop
}

View File

@@ -1,56 +1,27 @@
package com.bwssystems.hass;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.net.ssl.SSLContext;
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;
import com.bwssystems.HABridge.NamedIP;
import com.bwssystems.HABridge.api.NameValue;
import com.bwssystems.http.HTTPHandler;
import com.google.gson.Gson;
public class HomeAssistant {
private static final Logger log = LoggerFactory.getLogger(HomeAssistant.class);
private NamedIP hassAddress;
private HttpClient httpClient;
private CloseableHttpClient httpclientSSL;
private SSLContext sslcontext;
private SSLConnectionSocketFactory sslsf;
private RequestConfig globalConfig;
private HTTPHandler anHttpHandler;
public HomeAssistant(NamedIP addressName) {
super();
httpClient = HttpClients.createDefault();
// Trust own CA and all self-signed certs
sslcontext = SSLContexts.createDefault();
// Allow TLSv1 protocol only
sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null,
SSLConnectionSocketFactory.getDefaultHostnameVerifier());
globalConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build();
httpclientSSL = HttpClients.custom().setSSLSocketFactory(sslsf).setDefaultRequestConfig(globalConfig).build();
anHttpHandler = new HTTPHandler();
hassAddress = addressName;
}
@@ -82,7 +53,7 @@ public class HomeAssistant {
aUrl = aUrl + "/turn_off";
aBody = aBody + "}";
}
String theData = doHttpRequest(aUrl, HttpPost.METHOD_NAME, "application/json", aBody, headers);
String theData = anHttpHandler.doHttpRequest(aUrl, HttpPost.METHOD_NAME, "application/json", aBody, headers);
log.debug("call Command return is: <" + theData + ">");
return true;
}
@@ -93,7 +64,7 @@ public class HomeAssistant {
String theUrl = null;
String theData;
theUrl = "http://" + hassAddress.getIp() + ":" + hassAddress.getPort() + "/api/states";
theData = doHttpRequest(theUrl, HttpGet.METHOD_NAME, null, null, null);
theData = anHttpHandler.doHttpRequest(theUrl, HttpGet.METHOD_NAME, null, null, null);
if(theData != null) {
log.debug("GET Hass States - data: " + theData);
theHassStates = new Gson().fromJson(theData, State[].class);
@@ -109,98 +80,8 @@ public class HomeAssistant {
return theDeviceStates;
}
// This function executes the url from the device repository against the
// target as http or https as defined
protected String doHttpRequest(String url, String httpVerb, String contentType, String body, NameValue[] headers) {
HttpUriRequest request = null;
String theContent = null;
URI theURI = null;
ContentType parsedContentType = null;
StringEntity requestBody = null;
if (contentType != null && contentType.length() > 0) {
parsedContentType = ContentType.parse(contentType);
if (body != null && body.length() > 0)
requestBody = new StringEntity(body, parsedContentType);
}
try {
theURI = new URI(url);
} catch (URISyntaxException e1) {
log.warn("Error creating URI http request: " + url + " with message: " + e1.getMessage());
return null;
}
try {
if (HttpGet.METHOD_NAME.equalsIgnoreCase(httpVerb) || httpVerb == null) {
request = new HttpGet(theURI);
} else if (HttpPost.METHOD_NAME.equalsIgnoreCase(httpVerb)) {
HttpPost postRequest = new HttpPost(theURI);
if (requestBody != null)
postRequest.setEntity(requestBody);
request = postRequest;
} else if (HttpPut.METHOD_NAME.equalsIgnoreCase(httpVerb)) {
HttpPut putRequest = new HttpPut(theURI);
if (requestBody != null)
putRequest.setEntity(requestBody);
request = putRequest;
}
} catch (IllegalArgumentException e) {
log.warn("Error creating outbound http request: IllegalArgumentException in log", e);
return null;
}
log.debug("Making outbound call in doHttpRequest: " + request);
if (headers != null && headers.length > 0) {
for (int i = 0; i < headers.length; i++) {
request.setHeader(headers[i].getName(), headers[i].getValue());
}
}
try {
HttpResponse response;
if (url.startsWith("https"))
response = httpclientSSL.execute(request);
else
response = httpClient.execute(request);
log.debug((httpVerb == null ? "GET" : httpVerb) + " execute on URL responded: "
+ response.getStatusLine().getStatusCode());
if (response.getStatusLine().getStatusCode() >= 200 && response.getStatusLine().getStatusCode() < 300) {
if (response.getEntity() != null) {
try {
theContent = EntityUtils.toString(response.getEntity(), Charset.forName("UTF-8")); // read
// content
// for
// data
EntityUtils.consume(response.getEntity()); // close out
// inputstream
// ignore
// content
} catch (Exception e) {
log.debug(
"Error ocurred in handling response entity after successful call, still responding success. "
+ e.getMessage(),
e);
}
}
if (theContent == null)
theContent = "";
}
else {
EntityUtils.consume(response.getEntity()); // close out
// inputstream
// ignore
// content
}
} catch (IOException e) {
log.warn("Error calling out to HA gateway: IOException in log", e);
}
return theContent;
}
protected void closeClient() {
httpClient = null;
try {
httpclientSSL.close();
} catch (IOException e) {
// noop
}
httpclientSSL = null;
anHttpHandler.closeHandler();
}
}

View File

@@ -0,0 +1,138 @@
package com.bwssystems.http;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import javax.net.ssl.SSLContext;
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;
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 SSLContext sslcontext;
private SSLConnectionSocketFactory sslsf;
private RequestConfig globalConfig;
public HTTPHandler() {
httpClient = HttpClients.createDefault();
// Trust own CA and all self-signed certs
sslcontext = SSLContexts.createDefault();
// Allow TLSv1 protocol only
sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null,
SSLConnectionSocketFactory.getDefaultHostnameVerifier());
globalConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build();
httpclientSSL = HttpClients.custom().setSSLSocketFactory(sslsf).setDefaultRequestConfig(globalConfig).build();
}
// This function executes the url from the device repository against the
// target as http or https as defined
public String doHttpRequest(String url, String httpVerb, String contentType, String body, NameValue[] headers) {
HttpUriRequest request = null;
String theContent = null;
URI theURI = null;
ContentType parsedContentType = null;
StringEntity requestBody = null;
if (contentType != null && contentType.length() > 0) {
parsedContentType = ContentType.parse(contentType);
if (body != null && body.length() > 0)
requestBody = new StringEntity(body, parsedContentType);
}
try {
theURI = new URI(url);
} catch (URISyntaxException e1) {
log.warn("Error creating URI http request: " + url + " with message: " + e1.getMessage());
return null;
}
try {
if (HttpGet.METHOD_NAME.equalsIgnoreCase(httpVerb) || httpVerb == null) {
request = new HttpGet(theURI);
} else if (HttpPost.METHOD_NAME.equalsIgnoreCase(httpVerb)) {
HttpPost postRequest = new HttpPost(theURI);
if (requestBody != null)
postRequest.setEntity(requestBody);
request = postRequest;
} else if (HttpPut.METHOD_NAME.equalsIgnoreCase(httpVerb)) {
HttpPut putRequest = new HttpPut(theURI);
if (requestBody != null)
putRequest.setEntity(requestBody);
request = putRequest;
}
} catch (IllegalArgumentException e) {
log.warn("Error creating outbound http request: IllegalArgumentException in log", e);
return null;
}
log.debug("Making outbound call in doHttpRequest: " + request);
if (headers != null && headers.length > 0) {
for (int i = 0; i < headers.length; i++) {
request.setHeader(headers[i].getName(), headers[i].getValue());
}
}
try {
HttpResponse response;
if (url.startsWith("https"))
response = httpclientSSL.execute(request);
else
response = httpClient.execute(request);
log.debug((httpVerb == null ? "GET" : httpVerb) + " execute on URL responded: "
+ response.getStatusLine().getStatusCode());
if (response.getStatusLine().getStatusCode() >= 200 && response.getStatusLine().getStatusCode() < 300) {
if (response.getEntity() != null) {
try {
theContent = EntityUtils.toString(response.getEntity(), Charset.forName("UTF-8")); // read
// content
// for
// data
EntityUtils.consume(response.getEntity()); // close out
// inputstream
// ignore
// content
} catch (Exception e) {
log.debug(
"Error ocurred in handling response entity after successful call, still responding success. "
+ e.getMessage(),
e);
}
}
if (theContent == null)
theContent = "";
}
} catch (IOException e) {
log.warn("Error calling out to HA gateway: IOException in log", e);
}
return theContent;
}
public void closeHandler() {
httpClient = null;
try {
httpclientSSL.close();
} catch (IOException e) {
// noop
}
httpclientSSL = null;
}
}

View File

@@ -1,29 +1,70 @@
package com.bwssystems.http;
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.api.NameValue;
import com.bwssystems.HABridge.api.hue.DeviceState;
import com.bwssystems.HABridge.api.hue.StateChangeBody;
import com.bwssystems.HABridge.hue.BrightnessDecode;
import com.bwssystems.HABridge.hue.MultiCommandUtil;
import com.google.gson.Gson;
public class HTTPHome implements Home {
private static final Logger log = LoggerFactory.getLogger(HTTPHome.class);
private HTTPHandler anHttpHandler;
public HTTPHome() {
// TODO Auto-generated constructor stub
public HTTPHome(BridgeSettingsDescriptor bridgeSettings) {
super();
createHome(bridgeSettings);
}
@Override
public String deviceHandler(CallItem anItem, MultiCommandUtil aMultiUtil, String lightId, int iterationCount,
DeviceState state, StateChangeBody theStateChanges, boolean stateHasBri, boolean stateHasBriInc) {
// TODO Auto-generated method stub
return null;
String responseString = null;
log.debug("executing HUE api request to Http "
+ (anItem.getHttpVerb() == null ? "GET" : anItem.getHttpVerb()) + ": "
+ anItem.getItem().getAsString());
for (int x = 0; x < aMultiUtil.getSetCount(); x++) {
if (x > 0 || iterationCount > 0) {
try {
Thread.sleep(aMultiUtil.getTheDelay());
} catch (InterruptedException e) {
// ignore
}
}
if (anItem.getDelay() != null && anItem.getDelay() > 0)
aMultiUtil.setTheDelay(anItem.getDelay());
else
aMultiUtil.setTheDelay(aMultiUtil.getDelayDefault());
String anUrl = BrightnessDecode.calculateReplaceIntensityValue(anItem.getItem().getAsString(),
state, theStateChanges, stateHasBri, stateHasBriInc, false);
String aBody;
aBody = BrightnessDecode.calculateReplaceIntensityValue(anItem.getHttpBody(),
state, theStateChanges, stateHasBri, stateHasBriInc,
false);
// make call
if (anHttpHandler.doHttpRequest(anUrl, anItem.getHttpVerb(), anItem.getContentType(), aBody,
new Gson().fromJson(anItem.getHttpHeaders(), NameValue[].class)) == null) {
log.warn("Error on calling url to change device state: " + anUrl);
responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
+ "\",\"description\": \"Error on calling url to change device state\", \"parameter\": \"/lights/"
+ lightId + "state\"}}]";
x = aMultiUtil.getSetCount();
}
}
return responseString;
}
@Override
public Home createHome(BridgeSettingsDescriptor bridgeSettings) {
// TODO Auto-generated method stub
return null;
anHttpHandler = new HTTPHandler();
return this;
}
@Override
@@ -34,8 +75,7 @@ public class HTTPHome implements Home {
@Override
public void closeHome() {
// TODO Auto-generated method stub
anHttpHandler.closeHandler();
}
}

View File

@@ -1,20 +1,14 @@
package com.bwssystems.vera;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.ListIterator;
import java.util.Map;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.bwssystems.HABridge.NamedIP;
import com.bwssystems.http.HTTPHandler;
import com.bwssystems.luupRequests.Categorie;
import com.bwssystems.luupRequests.Device;
import com.bwssystems.luupRequests.Room;
@@ -25,13 +19,13 @@ import com.google.gson.Gson;
public class VeraInfo {
private static final Logger log = LoggerFactory.getLogger(VeraInfo.class);
private HttpClient httpClient;
private HTTPHandler httpClient;
private static final String SDATA_REQUEST = ":3480/data_request?id=sdata&output_format=json";
private NamedIP veraAddress;
public VeraInfo(NamedIP addressName) {
super();
httpClient = HttpClients.createDefault();
httpClient = new HTTPHandler();
veraAddress = addressName;
}
@@ -41,7 +35,7 @@ public class VeraInfo {
String theUrl = "http://" + veraAddress.getIp() + SDATA_REQUEST;
String theData;
theData = doHttpGETRequest(theUrl);
theData = httpClient.doHttpRequest(theUrl, null, null, null, null);
if(theData != null) {
theSdata = new Gson().fromJson(theData, Sdata.class);
log.debug("GET sdata - full: " + theSdata.getFull() + ", version: " + theSdata.getVersion());
@@ -88,22 +82,4 @@ public class VeraInfo {
theScene.setVeraname(veraAddress.getName());
}
}
// This function executes the url against the vera
protected String doHttpGETRequest(String url) {
String theContent = null;
log.debug("calling GET on URL: " + url);
HttpGet httpGet = new HttpGet(url);
try {
HttpResponse response = httpClient.execute(httpGet);
log.debug("GET on URL responded: " + response.getStatusLine().getStatusCode());
if(response.getStatusLine().getStatusCode() == 200){
theContent = EntityUtils.toString(response.getEntity(), Charset.forName("UTF-8")); //read content for data
EntityUtils.consume(response.getEntity()); //close out inputstream ignore content
}
} catch (IOException e) {
log.error("doHttpGETRequest: Error calling out to HA gateway: " + e.getMessage());
}
return theContent;
}
}