From 745986f08f538649c26934ee633638c7e996d0f6 Mon Sep 17 00:00:00 2001 From: Admin Date: Fri, 24 Feb 2017 15:45:45 -0600 Subject: [PATCH] Finished Domoticz updates --- pom.xml | 2 +- .../plugins/domoticz/DomoticzHandler.java | 62 +++++++++++++++---- .../plugins/domoticz/DomoticzHome.java | 56 ++++++++++++++--- .../HABridge/plugins/http/HTTPHandler.java | 42 ++++++------- 4 files changed, 121 insertions(+), 41 deletions(-) diff --git a/pom.xml b/pom.xml index ca0a205..b10f483 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.bwssystems.HABridge ha-bridge - 4.1.4c + 4.2.0 jar HA Bridge diff --git a/src/main/java/com/bwssystems/HABridge/plugins/domoticz/DomoticzHandler.java b/src/main/java/com/bwssystems/HABridge/plugins/domoticz/DomoticzHandler.java index 379c7b7..56ada5a 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/domoticz/DomoticzHandler.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/domoticz/DomoticzHandler.java @@ -3,11 +3,12 @@ package com.bwssystems.HABridge.plugins.domoticz; import java.util.ArrayList; import java.util.Iterator; import java.util.List; - +import java.util.Base64; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.bwssystems.HABridge.NamedIP; +import com.bwssystems.HABridge.api.NameValue; import com.bwssystems.HABridge.plugins.http.HTTPHandler; import com.google.gson.Gson; @@ -16,32 +17,33 @@ public class DomoticzHandler { private static final String GET_REQUEST = "/json.htm?type="; private static final String DEVICES_TYPE = "devices"; private static final String SCENES_TYPE = "scenes"; - private static final String FILTER_USED = "&used="; - private HTTPHandler httpClient; + private static final String FILTER_USED = "&used=true"; private NamedIP domoticzAddress; public DomoticzHandler(NamedIP addressName) { super(); - httpClient = new HTTPHandler(); domoticzAddress = addressName; } - public List getDevices() { - return getDomoticzDevices(GET_REQUEST, DEVICES_TYPE, FILTER_USED); + public List getDevices(HTTPHandler httpClient) { + return getDomoticzDevices(GET_REQUEST, DEVICES_TYPE, FILTER_USED, httpClient); } - public List getScenes() { - return getDomoticzDevices(GET_REQUEST, SCENES_TYPE, null); + public List getScenes(HTTPHandler httpClient) { + return getDomoticzDevices(GET_REQUEST, SCENES_TYPE, null, httpClient); } - private List getDomoticzDevices(String rootRequest, String type, String postpend) { + private List getDomoticzDevices(String rootRequest, String type, String postpend, HTTPHandler httpClient) { Devices theDomoticzApiResponse = null; List deviceList = null; String theUrl = null; String theData; - theUrl = "http://" + domoticzAddress.getIp() + ":" + domoticzAddress.getPort() + rootRequest + type; - theData = httpClient.doHttpRequest(theUrl, null, null, null, null); + if(postpend != null && !postpend.isEmpty()) + theUrl = buildUrl(rootRequest + type + postpend); + else + theUrl = buildUrl(rootRequest + type); + theData = httpClient.doHttpRequest(theUrl, null, null, null, buildHeaders()); if(theData != null) { log.debug("GET " + type + " DomoticzApiResponse - data: " + theData); theDomoticzApiResponse = new Gson().fromJson(theData, Devices.class); @@ -70,6 +72,44 @@ public class DomoticzHandler { return deviceList; } + public String buildUrl(String thePayload) { + String newUrl = null; + + if(thePayload != null && !thePayload.isEmpty()) { + if(domoticzAddress.getSecure() != null && domoticzAddress.getSecure()) + newUrl = "https://"; + else + newUrl = "http://"; + + newUrl = newUrl + domoticzAddress.getIp(); + + if(domoticzAddress.getPort() != null && !domoticzAddress.getPort().isEmpty()) + newUrl = newUrl + ":" + domoticzAddress.getPort(); + + if(thePayload.startsWith("/")) + newUrl = newUrl + thePayload; + else + newUrl = newUrl + "/" + thePayload; + } + + return newUrl; + } + + public NameValue[] buildHeaders() { + NameValue[] headers = null; + + if(domoticzAddress.getUsername() != null && !domoticzAddress.getUsername().isEmpty() + && domoticzAddress.getPassword() != null && !domoticzAddress.getPassword().isEmpty()) { + NameValue theAuth = new NameValue(); + theAuth.setName("Authorization"); + String encoding = Base64.getEncoder().encodeToString((domoticzAddress.getUsername() + ":" + domoticzAddress.getPassword()).getBytes()); + theAuth.setValue("Basic " + encoding); + headers = new NameValue[1]; + headers[0] = theAuth; + } + + return headers; + } public NamedIP getDomoticzAddress() { return domoticzAddress; } diff --git a/src/main/java/com/bwssystems/HABridge/plugins/domoticz/DomoticzHome.java b/src/main/java/com/bwssystems/HABridge/plugins/domoticz/DomoticzHome.java index ce08ecf..e03b40a 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/domoticz/DomoticzHome.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/domoticz/DomoticzHome.java @@ -1,6 +1,5 @@ package com.bwssystems.HABridge.plugins.domoticz; -import java.net.InetAddress; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -17,13 +16,16 @@ import com.bwssystems.HABridge.api.CallItem; import com.bwssystems.HABridge.api.hue.HueError; import com.bwssystems.HABridge.api.hue.HueErrorResponse; import com.bwssystems.HABridge.dao.DeviceDescriptor; +import com.bwssystems.HABridge.hue.BrightnessDecode; import com.bwssystems.HABridge.hue.MultiCommandUtil; +import com.bwssystems.HABridge.plugins.http.HTTPHandler; import com.google.gson.Gson; public class DomoticzHome implements Home { private static final Logger log = LoggerFactory.getLogger(DomoticzHome.class); private Map domoticzs; private Boolean validDomoticz; + private HTTPHandler httpClient; public DomoticzHome(BridgeSettingsDescriptor bridgeSettings) { super(); @@ -40,14 +42,14 @@ public class DomoticzHome implements Home { List deviceList = new ArrayList(); while(keys.hasNext()) { String key = keys.next(); - theResponse = domoticzs.get(key).getDevices(); + theResponse = domoticzs.get(key).getDevices(httpClient); if(theResponse != null) addDomoticzDevices(deviceList, theResponse, key); else { log.warn("Cannot get lights for Domoticz with name: " + key + ", skipping this Domoticz."); continue; } - theResponse = domoticzs.get(key).getScenes(); + theResponse = domoticzs.get(key).getScenes(httpClient); if(theResponse != null) addDomoticzDevices(deviceList, theResponse, key); else @@ -70,6 +72,7 @@ public class DomoticzHome implements Home { @Override public String deviceHandler(CallItem anItem, MultiCommandUtil aMultiUtil, String lightId, int intensity, Integer targetBri,Integer targetBriInc, DeviceDescriptor device, String body) { + Devices theDomoticzApiResponse = null; String responseString = null; String theUrl = anItem.getItem().getAsString(); @@ -78,13 +81,38 @@ public class DomoticzHome implements Home { String hostPortion = intermediate.substring(0, intermediate.indexOf('/')); String theUrlBody = intermediate.substring(intermediate.indexOf('/') + 1); String hostAddr = null; - String port = null; if (hostPortion.contains(":")) { hostAddr = hostPortion.substring(0, intermediate.indexOf(':')); - port = hostPortion.substring(intermediate.indexOf(':') + 1); } else hostAddr = hostPortion; - + DomoticzHandler theHandler = findHandlerByAddress(hostAddr); + if(theHandler != null){ + String theData; + String anUrl = BrightnessDecode.calculateReplaceIntensityValue(theUrlBody, + intensity, targetBri, targetBriInc, false); + theData = httpClient.doHttpRequest(theHandler.buildUrl(anUrl), null, null, null, theHandler.buildHeaders()); + try { + theDomoticzApiResponse = new Gson().fromJson(theData, Devices.class); + if(theDomoticzApiResponse.getStatus().equals("OK")) + responseString = null; + else { + log.warn("Call failed for Domoticz " + theHandler.getDomoticzAddress().getName() + " with status " + theDomoticzApiResponse.getStatus() + " for item " + theDomoticzApiResponse.getTitle()); + responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId, + "Error on calling url to change device state", "/lights/" + + lightId + "state", null, null).getTheErrors(), HueError[].class); + } + } catch (Exception e) { + log.warn("Cannot interrpret result from call for Domoticz " + theHandler.getDomoticzAddress().getName() + " as response is not parsable."); + responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId, + "Error on calling url to change device state", "/lights/" + + lightId + "state", null, null).getTheErrors(), HueError[].class); + } + } else { + log.warn("Domoticz Call could not complete, no address found: " + theUrl); + responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId, + "Error on calling url to change device state", "/lights/" + + lightId + "state", null, null).getTheErrors(), HueError[].class); + } } else { log.warn("Domoticz Call to be presented as http(s)://(:)/payload, format of request unknown: " + theUrl); responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId, @@ -100,6 +128,7 @@ public class DomoticzHome implements Home { log.info("Domoticz Home created." + (validDomoticz ? "" : " No Domoticz devices configured.")); if(!validDomoticz) return null; + httpClient = new HTTPHandler(); domoticzs = new HashMap(); Iterator theList = bridgeSettings.getDomoticzaddress().getDevices().iterator(); while(theList.hasNext()) { @@ -116,12 +145,23 @@ public class DomoticzHome implements Home { private DomoticzHandler findHandlerByAddress(String hostAddress) { DomoticzHandler aHandler = null; - + boolean found = false; + Iterator keys = domoticzs.keySet().iterator(); + while(keys.hasNext()) { + String key = keys.next(); + aHandler = domoticzs.get(key); + if(aHandler != null && aHandler.getDomoticzAddress().getIp().equals(hostAddress)) { + found = true; + break; + } + } + if(!found) + aHandler = null; return aHandler; } @Override public void closeHome() { - // noop + httpClient.closeHandler(); } } diff --git a/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHandler.java b/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHandler.java index 245b729..5a78902 100644 --- a/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHandler.java +++ b/src/main/java/com/bwssystems/HABridge/plugins/http/HTTPHandler.java @@ -4,6 +4,7 @@ import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.nio.charset.Charset; + import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; @@ -11,20 +12,20 @@ import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.ssl.SSLContexts; + 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; @@ -33,23 +34,23 @@ 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 HttpClient httpClient; + private CloseableHttpClient httpClient; // private SSLContext sslcontext; // private SSLConnectionSocketFactory sslsf; -// private RequestConfig globalConfig; + private RequestConfig globalConfig; public HTTPHandler() { - httpClient = HttpClients.createDefault(); +// httpClient = HttpClients.createDefault(); // Removed Specific SSL as Apache HttpClient automatically uses SSL if the URI starts with https:// // Trust own CA and all self-signed certs // sslcontext = SSLContexts.createDefault(); // Allow TLSv1 protocol only // sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLS" }, null, // SSLConnectionSocketFactory.getDefaultHostnameVerifier()); -// globalConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build(); -// httpclientSSL = HttpClients.custom().setSSLSocketFactory(sslsf).setDefaultRequestConfig(globalConfig).build(); + globalConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build(); + httpClient = HttpClients.custom().setDefaultRequestConfig(globalConfig).build(); } @@ -142,23 +143,22 @@ public class HTTPHandler { return theContent; } - public HttpClient getHttpClient() { +// public HttpClient getHttpClient() { +// return httpClient; +// } + + + public CloseableHttpClient getHttpClient() { return httpClient; } -// public CloseableHttpClient getHttpclientSSL() { -// return httpclientSSL; -// } - - public void closeHandler() { + try { + httpClient.close(); + } catch (IOException e) { + // noop + } httpClient = null; -// try { -// httpclientSSL.close(); -// } catch (IOException e) { -// // noop -// } -// httpclientSSL = null; } }