From 8cd571c18392d78d02071584de845ecfba406fc2 Mon Sep 17 00:00:00 2001 From: Niklas Date: Fri, 23 Dec 2016 19:57:34 +0100 Subject: [PATCH 1/3] Added a optional webhook for harmony-activity changes --- .../HABridge/HttpRequestHelper.java | 139 ++++++++++++++++++ .../java/com/bwssystems/HABridge/NamedIP.java | 11 +- .../bwssystems/HABridge/hue/HueMulator.java | 136 ++--------------- .../com/bwssystems/harmony/HarmonyServer.java | 127 +++++++++------- src/main/java/com/bwssystems/hue/HueInfo.java | 10 +- src/main/java/com/bwssystems/hue/HueUtil.java | 6 +- src/main/resources/public/scripts/app.js | 13 +- src/main/resources/public/views/system.html | 19 ++- 8 files changed, 265 insertions(+), 196 deletions(-) create mode 100644 src/main/java/com/bwssystems/HABridge/HttpRequestHelper.java diff --git a/src/main/java/com/bwssystems/HABridge/HttpRequestHelper.java b/src/main/java/com/bwssystems/HABridge/HttpRequestHelper.java new file mode 100644 index 0000000..a960f5a --- /dev/null +++ b/src/main/java/com/bwssystems/HABridge/HttpRequestHelper.java @@ -0,0 +1,139 @@ +package com.bwssystems.HABridge; + +import com.bwssystems.HABridge.api.NameValue; +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 java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.charset.Charset; +import javax.net.ssl.SSLContext; + +/** + * Simple Helper-Class to Call HTTP- and HTTPS-URLs + * + * Created by CrEaK on 23.12.16 19:34. + */ +public enum HttpRequestHelper { + + INSTANCE; + + private static final Logger log = LoggerFactory.getLogger(HttpRequestHelper.class); + + + private HttpClient httpClient; + private CloseableHttpClient httpclientSSL; + private SSLContext sslcontext; + private SSLConnectionSocketFactory sslsf; + private RequestConfig globalConfig; + + HttpRequestHelper() { + this.httpClient = HttpClients.createDefault(); + // Trust own CA and all self-signed certs + this.sslcontext = SSLContexts.createDefault(); + // Allow TLSv1 protocol only + this.sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null, + SSLConnectionSocketFactory.getDefaultHostnameVerifier()); + this.globalConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build(); + this.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 HttpClient getHttpClient() { + return httpClient; + } +} diff --git a/src/main/java/com/bwssystems/HABridge/NamedIP.java b/src/main/java/com/bwssystems/HABridge/NamedIP.java index 38a6d7f..77e7e51 100644 --- a/src/main/java/com/bwssystems/HABridge/NamedIP.java +++ b/src/main/java/com/bwssystems/HABridge/NamedIP.java @@ -2,7 +2,8 @@ package com.bwssystems.HABridge; public class NamedIP { private String name; - private String ip; + private String ip; + private String webhook; private String port; private String username; private String password; @@ -19,7 +20,13 @@ public class NamedIP { public void setIp(String ip) { this.ip = ip; } - public String getPort() { + public String getWebhook() { + return webhook; + } + public void setWebhook(final String webhook) { + this.webhook = webhook; + } + public String getPort() { return port; } public void setPort(String port) { diff --git a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java index 2e1d66a..27a88d0 100644 --- a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java +++ b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java @@ -2,8 +2,8 @@ package com.bwssystems.HABridge.hue; import com.bwssystems.HABridge.BridgeSettingsDescriptor; import com.bwssystems.HABridge.DeviceMapTypes; +import com.bwssystems.HABridge.HttpRequestHelper; import com.bwssystems.HABridge.api.CallItem; -import com.bwssystems.HABridge.api.CallItemDeserializer; import com.bwssystems.HABridge.api.NameValue; import com.bwssystems.HABridge.api.UserCreateRequest; import com.bwssystems.HABridge.api.hue.DeviceResponse; @@ -34,7 +34,6 @@ import com.bwssystems.nest.controller.Nest; import com.bwssystems.util.JsonTransformer; import com.bwssystems.util.UDPDatagramSender; import com.google.gson.Gson; -import com.google.gson.GsonBuilder; import net.java.dev.eval.Expression; @@ -43,22 +42,9 @@ import static spark.Spark.options; import static spark.Spark.post; import static spark.Spark.put; -import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; -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; @@ -69,9 +55,6 @@ import java.math.BigDecimal; import java.math.BigInteger; import java.net.InetAddress; import java.net.Socket; -import java.net.URI; -import java.net.URISyntaxException; -import java.nio.charset.Charset; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -80,7 +63,6 @@ import java.util.Set; import java.util.StringTokenizer; import java.util.UUID; -import javax.net.ssl.SSLContext; import javax.xml.bind.DatatypeConverter; /** @@ -101,11 +83,6 @@ public class HueMulator implements HueErrorStringSet { private Nest theNest; private HueHome myHueHome; private MQTTHome mqttHome; - private HttpClient httpClient; - private CloseableHttpClient httpclientSSL; - private SSLContext sslcontext; - private SSLConnectionSocketFactory sslsf; - private RequestConfig globalConfig; private BridgeSettingsDescriptor bridgeSettings; private UDPDatagramSender theUDPDatagramSender; private byte[] sendData; @@ -116,15 +93,6 @@ public class HueMulator implements HueErrorStringSet { public HueMulator(BridgeSettingsDescriptor theBridgeSettings, DeviceRepository aDeviceRepository, HarmonyHome theHarmonyHome, NestHome aNestHome, HueHome aHueHome, MQTTHome aMqttHome, UDPDatagramSender aUdpDatagramSender) { - 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(); - repository = aDeviceRepository; if (theBridgeSettings.isValidHarmony()) this.myHarmonyHome = theHarmonyHome; @@ -309,7 +277,7 @@ public class HueMulator implements HueErrorStringSet { if ((device.getMapType() != null && device.getMapType().equalsIgnoreCase("hueDevice"))) { HueDeviceIdentifier deviceId = new Gson().fromJson(device.getOnUrl(), HueDeviceIdentifier.class); if (myHueHome.getTheHUERegisteredUser() == null) { - hueUser = HueUtil.registerWithHue(httpClient, deviceId.getIpAddress(), device.getName(), + hueUser = HueUtil.registerWithHue(deviceId.getIpAddress(), device.getName(), myHueHome.getTheHUERegisteredUser(), this); if (hueUser == null) { return errorString; @@ -317,7 +285,7 @@ public class HueMulator implements HueErrorStringSet { myHueHome.setTheHUERegisteredUser(hueUser); } // make call - responseString = doHttpRequest( + responseString = HttpRequestHelper.INSTANCE.doHttpRequest( "http://" + deviceId.getIpAddress() + "/api/" + myHueHome.getTheHUERegisteredUser() + "/lights/" + deviceId.getDeviceId(), HttpGet.METHOD_NAME, device.getContentType(), null, null); @@ -327,7 +295,7 @@ public class HueMulator implements HueErrorStringSet { } else if (responseString.contains("[{\"error\":") && responseString.contains("unauthorized user")) { myHueHome.setTheHUERegisteredUser(null); - hueUser = HueUtil.registerWithHue(httpClient, deviceId.getIpAddress(), device.getName(), + hueUser = HueUtil.registerWithHue(deviceId.getIpAddress(), device.getName(), myHueHome.getTheHUERegisteredUser(), this); if (hueUser == null) { return errorString; @@ -527,7 +495,7 @@ public class HueMulator implements HueErrorStringSet { if ((device.getMapType() != null && device.getMapType().equalsIgnoreCase("hueDevice"))) { HueDeviceIdentifier deviceId = new Gson().fromJson(device.getOnUrl(), HueDeviceIdentifier.class); if (myHueHome.getTheHUERegisteredUser() == null) { - hueUser = HueUtil.registerWithHue(httpClient, deviceId.getIpAddress(), device.getName(), + hueUser = HueUtil.registerWithHue(deviceId.getIpAddress(), device.getName(), myHueHome.getTheHUERegisteredUser(), this); if (hueUser == null) { return errorString; @@ -535,15 +503,15 @@ public class HueMulator implements HueErrorStringSet { myHueHome.setTheHUERegisteredUser(hueUser); } // make call - responseString = doHttpRequest("http://" + deviceId.getIpAddress() + "/api/" + responseString = HttpRequestHelper.INSTANCE.doHttpRequest("http://" + deviceId.getIpAddress() + "/api/" + myHueHome.getTheHUERegisteredUser() + "/lights/" + deviceId.getDeviceId(), - HttpGet.METHOD_NAME, device.getContentType(), null, null); + HttpGet.METHOD_NAME, device.getContentType(), null, null); if (responseString == null) { log.warn("Error on calling hue device to get state: " + device.getName()); lightResponse = DeviceResponse.createResponse(device); } else if (responseString.contains("[{\"error\":") && responseString.contains("unauthorized user")) { myHueHome.setTheHUERegisteredUser(null); - hueUser = HueUtil.registerWithHue(httpClient, deviceId.getIpAddress(), device.getName(), + hueUser = HueUtil.registerWithHue(deviceId.getIpAddress(), device.getName(), myHueHome.getTheHUERegisteredUser(), this); if (hueUser == null) { return errorString; @@ -800,7 +768,7 @@ public class HueMulator implements HueErrorStringSet { HueDeviceIdentifier deviceId = new Gson().fromJson(callItems[i].getItem(), HueDeviceIdentifier.class); if (myHueHome.getTheHUERegisteredUser() == null) { - hueUser = HueUtil.registerWithHue(httpClient, deviceId.getIpAddress(), device.getName(), + hueUser = HueUtil.registerWithHue(deviceId.getIpAddress(), device.getName(), myHueHome.getTheHUERegisteredUser(), this); if (hueUser == null) { return errorString; @@ -817,7 +785,7 @@ public class HueMulator implements HueErrorStringSet { theDelay = callItems[i].getDelay(); else theDelay = bridgeSettings.getButtonsleep(); - responseString = doHttpRequest( + responseString = HttpRequestHelper.INSTANCE.doHttpRequest( "http://" + deviceId.getIpAddress() + "/api/" + myHueHome.getTheHUERegisteredUser() + "/lights/" + deviceId.getDeviceId() + "/state", HttpPut.METHOD_NAME, device.getContentType(), request.body(), null); @@ -832,7 +800,7 @@ public class HueMulator implements HueErrorStringSet { } else if (responseString.contains("[{\"error\":")) { if(responseString.contains("unauthorized user")) { myHueHome.setTheHUERegisteredUser(null); - hueUser = HueUtil.registerWithHue(httpClient, deviceId.getIpAddress(), device.getName(), + hueUser = HueUtil.registerWithHue(deviceId.getIpAddress(), device.getName(), myHueHome.getTheHUERegisteredUser(), this); if (hueUser == null) { return errorString; @@ -1132,8 +1100,8 @@ public class HueMulator implements HueErrorStringSet { calculateIntensity(state, theStateChanges, stateHasBri, stateHasBriInc), false); // make call - if (doHttpRequest(anUrl, device.getHttpVerb(), device.getContentType(), body, - theHeaders) == null) { + if (HttpRequestHelper.INSTANCE.doHttpRequest(anUrl, device.getHttpVerb(), device.getContentType(), body, + theHeaders) == 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/" @@ -1239,84 +1207,6 @@ public class HueMulator implements HueErrorStringSet { return request; } - // 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 = ""; - } - } catch (IOException e) { - log.warn("Error calling out to HA gateway: IOException in log", e); - } - return theContent; - } - private String doExecRequest(String anItem, int intensity, String lightId) { log.debug("Executing request: " + anItem); String responseString = null; diff --git a/src/main/java/com/bwssystems/harmony/HarmonyServer.java b/src/main/java/com/bwssystems/harmony/HarmonyServer.java index 2dbf028..4baa7b1 100644 --- a/src/main/java/com/bwssystems/harmony/HarmonyServer.java +++ b/src/main/java/com/bwssystems/harmony/HarmonyServer.java @@ -4,6 +4,8 @@ import static java.lang.String.format; import javax.inject.Inject; +import com.bwssystems.HABridge.HttpRequestHelper; +import org.apache.http.client.methods.HttpGet; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -18,10 +20,16 @@ import net.whistlingfish.harmony.HarmonyClientModule; import net.whistlingfish.harmony.config.Activity; import net.whistlingfish.harmony.protocol.OAReplyProvider; +import java.net.URLEncoder; + public class HarmonyServer { + + private static final String ACTIVIY_ID = "${activity.id}"; + private static final String ACTIVIY_LABEL = "${activity.label}"; + @Inject private HarmonyClient harmonyClient; - + private HarmonyHandler myHarmony; private DevModeResponse devResponse; private OAReplyProvider dummyProvider; @@ -29,58 +37,77 @@ public class HarmonyServer { private Boolean isDevMode; private Logger log = LoggerFactory.getLogger(HarmonyServer.class); - public HarmonyServer(NamedIP theHarmonyAddress) { - super(); - myHarmony = null; - dummyProvider = null; - myNameAndIP = theHarmonyAddress; - isDevMode = false; - } + public HarmonyServer(NamedIP theHarmonyAddress) { + super(); + myHarmony = null; + dummyProvider = null; + myNameAndIP = theHarmonyAddress; + isDevMode = false; + } - public static HarmonyServer setup(BridgeSettingsDescriptor bridgeSettings, Boolean harmonyDevMode, NamedIP theHarmonyAddress) throws Exception { - if(!bridgeSettings.isValidHarmony() && harmonyDevMode) { - return new HarmonyServer(theHarmonyAddress); - } - Injector injector = null; - if(!harmonyDevMode) - injector = Guice.createInjector(new HarmonyClientModule()); - HarmonyServer mainObject = new HarmonyServer(theHarmonyAddress); - if(!harmonyDevMode) - injector.injectMembers(mainObject); - mainObject.execute(bridgeSettings, harmonyDevMode); - return mainObject; - } - - private void execute(BridgeSettingsDescriptor mySettings, Boolean harmonyDevMode) throws Exception { - Boolean noopCalls = Boolean.parseBoolean(System.getProperty("noop.calls", "false")); - isDevMode = harmonyDevMode; - String modeString = ""; - if(dummyProvider != null) - log.debug("something is very wrong as dummyProvider is not null..."); - if(isDevMode) - modeString = " (development mode)"; - else if(noopCalls) - modeString = " (no op calls to harmony)"; - log.info("setup initiated " + modeString + "...."); - if(isDevMode) - { - harmonyClient = null; - devResponse = new DevModeResponse(); + public static HarmonyServer setup( + BridgeSettingsDescriptor bridgeSettings, + Boolean harmonyDevMode, + NamedIP theHarmonyAddress + ) throws Exception { + if (!bridgeSettings.isValidHarmony() && harmonyDevMode) { + return new HarmonyServer(theHarmonyAddress); } - else { - devResponse = null; - harmonyClient.addListener(new ActivityChangeListener() { - @Override - public void activityStarted(Activity activity) { - log.info(format("activity changed: [%d] %s", activity.getId(), activity.getLabel())); - } - }); - harmonyClient.connect(myNameAndIP.getIp()); + Injector injector = null; + if (!harmonyDevMode) { + injector = Guice.createInjector(new HarmonyClientModule()); + } + HarmonyServer mainObject = new HarmonyServer(theHarmonyAddress); + if (!harmonyDevMode) { + injector.injectMembers(mainObject); + } + mainObject.execute(bridgeSettings, harmonyDevMode); + return mainObject; + } + + private void execute(BridgeSettingsDescriptor mySettings, Boolean harmonyDevMode) throws Exception { + Boolean noopCalls = Boolean.parseBoolean(System.getProperty("noop.calls", "false")); + isDevMode = harmonyDevMode; + String modeString = ""; + if (dummyProvider != null) { + log.debug("something is very wrong as dummyProvider is not null..."); + } + if (isDevMode) { + modeString = " (development mode)"; + } else if (noopCalls) { + modeString = " (no op calls to harmony)"; + } + log.info("setup initiated " + modeString + "...."); + if (isDevMode) { + harmonyClient = null; + devResponse = new DevModeResponse(); + } else { + devResponse = null; + harmonyClient.addListener(new ActivityChangeListener() { + @Override + public void activityStarted(Activity activity) { + String webhook = myNameAndIP.getWebhook(); + try { + // Replacing variables + webhook = webhook.replace(ACTIVIY_ID, activity.getId().toString()); + webhook = webhook.replace(ACTIVIY_LABEL, URLEncoder.encode(activity.getLabel(), "UTF-8")); + + log.info(format("calling webhook: %s", webhook)); + + // Calling webhook + HttpRequestHelper.INSTANCE.doHttpRequest(webhook, HttpGet.METHOD_NAME, null, null, null); + } catch (Exception e) { + log.warn("could not call webhook: " + webhook, e); + } + log.info(format("activity changed: [%d] %s", activity.getId(), activity.getLabel())); + } + }); + harmonyClient.connect(myNameAndIP.getIp()); } myHarmony = new HarmonyHandler(harmonyClient, noopCalls, devResponse); - } + } - public HarmonyHandler getMyHarmony() { - return myHarmony; - } + public HarmonyHandler getMyHarmony() { + return myHarmony; + } } diff --git a/src/main/java/com/bwssystems/hue/HueInfo.java b/src/main/java/com/bwssystems/hue/HueInfo.java index 7b9a265..2738291 100644 --- a/src/main/java/com/bwssystems/hue/HueInfo.java +++ b/src/main/java/com/bwssystems/hue/HueInfo.java @@ -2,10 +2,10 @@ package com.bwssystems.hue; import java.io.IOException; import java.nio.charset.Charset; + +import com.bwssystems.HABridge.HttpRequestHelper; 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; @@ -17,7 +17,6 @@ import com.google.gson.Gson; public class HueInfo implements HueErrorStringSet { private static final Logger log = LoggerFactory.getLogger(HueInfo.class); - private HttpClient httpClient; private NamedIP hueAddress; private String theUser; private HueHome theHueHome; @@ -25,7 +24,6 @@ public class HueInfo implements HueErrorStringSet { public HueInfo(NamedIP addressName, HueHome aHueHome) { super(); - httpClient = HttpClients.createDefault(); hueAddress = addressName; theUser = "habridge"; theHueHome = aHueHome; @@ -50,7 +48,7 @@ public class HueInfo implements HueErrorStringSet { log.debug("GET HueApiResponse - data: " + theData); if(theData.contains("[{\"error\":")) { if(theData.contains("unauthorized user")) { - theUser = HueUtil.registerWithHue(httpClient, hueAddress.getIp(), hueAddress.getName(), theHueHome.getTheHUERegisteredUser(), this); + theUser = HueUtil.registerWithHue(hueAddress.getIp(), hueAddress.getName(), theHueHome.getTheHUERegisteredUser(), this); if(theUser == null) { log.warn("Register to Hue for " + hueAddress.getName() + " returned error: " + errorString); return null; @@ -84,7 +82,7 @@ public class HueInfo implements HueErrorStringSet { log.debug("calling GET on URL: " + url); HttpGet httpGet = new HttpGet(url); try { - HttpResponse response = httpClient.execute(httpGet); + HttpResponse response = HttpRequestHelper.INSTANCE.getHttpClient().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 diff --git a/src/main/java/com/bwssystems/hue/HueUtil.java b/src/main/java/com/bwssystems/hue/HueUtil.java index d2806f0..c196ae7 100644 --- a/src/main/java/com/bwssystems/hue/HueUtil.java +++ b/src/main/java/com/bwssystems/hue/HueUtil.java @@ -2,8 +2,8 @@ package com.bwssystems.hue; import java.io.IOException; +import com.bwssystems.HABridge.HttpRequestHelper; import org.apache.http.HttpResponse; -import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; @@ -19,7 +19,7 @@ public class HueUtil { private static final Logger log = LoggerFactory.getLogger(HueUtil.class); public static final String HUE_REQUEST = "/api"; - public static final String registerWithHue(HttpClient anHttpClient, String ipAddress, String aName, String theUser, HueErrorStringSet errorStringSet) { + public static final String registerWithHue(String ipAddress, String aName, String theUser, HueErrorStringSet errorStringSet) { UserCreateRequest theLogin = new UserCreateRequest(); theLogin.setDevicetype("HABridge#MyMachine"); HttpPost postRequest = new HttpPost("http://" + ipAddress + HUE_REQUEST); @@ -28,7 +28,7 @@ public class HueUtil { HttpResponse response = null; postRequest.setEntity(requestBody); try { - response = anHttpClient.execute(postRequest); + response = HttpRequestHelper.INSTANCE.getHttpClient().execute(postRequest); log.debug("POST execute on URL responded: " + response.getStatusLine().getStatusCode()); if(response.getStatusLine().getStatusCode() >= 200 && response.getStatusLine().getStatusCode() < 300){ String theBody = EntityUtils.toString(response.getEntity()); diff --git a/src/main/resources/public/scripts/app.js b/src/main/resources/public/scripts/app.js index 9f47957..8476c4b 100644 --- a/src/main/resources/public/scripts/app.js +++ b/src/main/resources/public/scripts/app.js @@ -654,18 +654,21 @@ app.controller('SystemController', function ($scope, $location, $http, $window, } } }; - $scope.addHarmonytoSettings = function (newharmonyname, newharmonyip) { + $scope.addHarmonytoSettings = function (newharmonyname, newharmonyip, newharmonywebhook) { if($scope.bridge.settings.harmonyaddress == null) { $scope.bridge.settings.harmonyaddress = { devices: [] }; } - var newharmony = {name: newharmonyname, ip: newharmonyip } + var newharmony = {name: newharmonyname, ip: newharmonyip , webhook: newharmonywebhook } $scope.bridge.settings.harmonyaddress.devices.push(newharmony); $scope.newharmonyname = null; - $scope.newharmonyip = null; + $scope.newharmonyip = null; + $scope.newharmonywebhook = null; }; - $scope.removeHarmonytoSettings = function (harmonyname, harmonyip) { + $scope.removeHarmonytoSettings = function (harmonyname, harmonyip, harmonywebhook) { for(var i = $scope.bridge.settings.harmonyaddress.devices.length - 1; i >= 0; i--) { - if($scope.bridge.settings.harmonyaddress.devices[i].name === harmonyname && $scope.bridge.settings.harmonyaddress.devices[i].ip === harmonyip) { + if($scope.bridge.settings.harmonyaddress.devices[i].name === harmonyname + && $scope.bridge.settings.harmonyaddress.devices[i].ip === harmonyip + && $scope.bridge.settings.harmonyaddress.devices[i].webhook === harmonywebhook) { $scope.bridge.settings.harmonyaddress.devices.splice(i, 1); } } diff --git a/src/main/resources/public/views/system.html b/src/main/resources/public/views/system.html index 89a9318..afcc19a 100644 --- a/src/main/resources/public/views/system.html +++ b/src/main/resources/public/views/system.html @@ -138,25 +138,30 @@ Name - IP + IP + Webhook Manage {{harmony.name}} - {{harmony.ip}} + {{harmony.ip}} + {{harmony.webhook}} + ng-click="removeHarmonytoSettings(harmony.name, harmony.ip, harmony.webhook)">Del - + + + ng-click="addHarmonytoSettings(newharmonyname, newharmonyip, newharmonywebhook)">Add From e36145f21621792b510971dd836fefd0138cb60c Mon Sep 17 00:00:00 2001 From: Niklas Date: Tue, 27 Dec 2016 13:33:27 +0100 Subject: [PATCH 2/3] NPE-Check for harmony webhook --- .../com/bwssystems/harmony/HarmonyServer.java | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/bwssystems/harmony/HarmonyServer.java b/src/main/java/com/bwssystems/harmony/HarmonyServer.java index 4baa7b1..59f345d 100644 --- a/src/main/java/com/bwssystems/harmony/HarmonyServer.java +++ b/src/main/java/com/bwssystems/harmony/HarmonyServer.java @@ -87,17 +87,19 @@ public class HarmonyServer { @Override public void activityStarted(Activity activity) { String webhook = myNameAndIP.getWebhook(); - try { - // Replacing variables - webhook = webhook.replace(ACTIVIY_ID, activity.getId().toString()); - webhook = webhook.replace(ACTIVIY_LABEL, URLEncoder.encode(activity.getLabel(), "UTF-8")); + if(webhook != null) { + try { + // Replacing variables + webhook = webhook.replace(ACTIVIY_ID, activity.getId().toString()); + webhook = webhook.replace(ACTIVIY_LABEL, URLEncoder.encode(activity.getLabel(), "UTF-8")); - log.info(format("calling webhook: %s", webhook)); + log.info(format("calling webhook: %s", webhook)); - // Calling webhook - HttpRequestHelper.INSTANCE.doHttpRequest(webhook, HttpGet.METHOD_NAME, null, null, null); - } catch (Exception e) { - log.warn("could not call webhook: " + webhook, e); + // Calling webhook + HttpRequestHelper.INSTANCE.doHttpRequest(webhook, HttpGet.METHOD_NAME, null, null, null); + } catch (Exception e) { + log.warn("could not call webhook: " + webhook, e); + } } log.info(format("activity changed: [%d] %s", activity.getId(), activity.getLabel())); } From 3fea7f4f1aad58ccd3580b4d4ddbc1a6a19d56ad Mon Sep 17 00:00:00 2001 From: Niklas Date: Wed, 8 Feb 2017 08:29:37 +0100 Subject: [PATCH 3/3] Change to Generic HTTPClient --- .../bwssystems/HABridge/plugins/harmony/HarmonyServer.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/bwssystems/HABridge/plugins/harmony/HarmonyServer.java b/src/main/java/com/bwssystems/HABridge/plugins/harmony/HarmonyServer.java index b9cb404..521f7ed 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/harmony/HarmonyServer.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/harmony/HarmonyServer.java @@ -4,7 +4,7 @@ import static java.lang.String.format; import javax.inject.Inject; -import com.bwssystems.HABridge.HttpRequestHelper; +import com.bwssystems.HABridge.plugins.http.HTTPHandler; import org.apache.http.client.methods.HttpGet; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,6 +35,7 @@ public class HarmonyServer { private OAReplyProvider dummyProvider; private NamedIP myNameAndIP; private Boolean isDevMode; + private HTTPHandler httpClient; private Logger log = LoggerFactory.getLogger(HarmonyServer.class); public HarmonyServer(NamedIP theHarmonyAddress) { @@ -43,6 +44,7 @@ public class HarmonyServer { dummyProvider = null; myNameAndIP = theHarmonyAddress; isDevMode = false; + httpClient = new HTTPHandler(); } public static HarmonyServer setup( @@ -96,7 +98,7 @@ public class HarmonyServer { log.info(format("calling webhook: %s", webhook)); // Calling webhook - HttpRequestHelper.INSTANCE.doHttpRequest(webhook, HttpGet.METHOD_NAME, null, null, null); + httpClient.doHttpRequest(webhook, HttpGet.METHOD_NAME, null, null, null); } catch (Exception e) { log.warn("could not call webhook: " + webhook, e); }