diff --git a/pom.xml b/pom.xml
index 523a613..8b7a066 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
com.bwssystems.HABridge
ha-bridge
- 3.5.1i
+ 3.5.1j
jar
HA Bridge
diff --git a/src/main/java/com/bwssystems/HABridge/DeviceMapTypes.java b/src/main/java/com/bwssystems/HABridge/DeviceMapTypes.java
index 3aef2fb..77738c0 100644
--- a/src/main/java/com/bwssystems/HABridge/DeviceMapTypes.java
+++ b/src/main/java/com/bwssystems/HABridge/DeviceMapTypes.java
@@ -16,6 +16,7 @@ public class DeviceMapTypes {
public final static String[] HAL_THERMO_SET = { "halThermoSet", "HAL Thermostat"};
public final static String[] MQTT_MESSAGE = { "mqttMessage", "MQTT Message"};
public final static String[] EXEC_DEVICE = { "execDevice", "Execute Script/Program"};
+ public final static String[] HASS_DEVICE = { "hassDevice", "HomeAssistant Device"};
public final static int typeIndex = 0;
public final static int displayIndex = 1;
@@ -34,6 +35,7 @@ public class DeviceMapTypes {
public String[] halThermoSet;
public String[] mqttMessage;
public String[] execDevice;
+ public String[] hassDevice;
public int typeindex;
public int displayindex;
@@ -57,6 +59,7 @@ public class DeviceMapTypes {
this.setTypeindex(typeIndex);
this.setVeraDevice(VERA_DEVICE);
this.setVeraScene(VERA_SCENE);
+ this.setHassDevice(HASS_DEVICE);
}
public String[] getCustomDevice() {
return customDevice;
@@ -142,6 +145,12 @@ public class DeviceMapTypes {
public void setExecDevice(String[] execDevice) {
this.execDevice = execDevice;
}
+ public String[] getHassDevice() {
+ return hassDevice;
+ }
+ public void setHassDevice(String[] hassDevice) {
+ this.hassDevice = hassDevice;
+ }
public int getTypeindex() {
return typeindex;
}
diff --git a/src/main/java/com/bwssystems/HABridge/HABridge.java b/src/main/java/com/bwssystems/HABridge/HABridge.java
index 55a89d5..897c457 100644
--- a/src/main/java/com/bwssystems/HABridge/HABridge.java
+++ b/src/main/java/com/bwssystems/HABridge/HABridge.java
@@ -92,7 +92,7 @@ public class HABridge {
}
else {
// setup the class to handle the hue emulator rest api
- theHueMulator = new HueMulator(bridgeSettings.getBridgeSettingsDescriptor(), theResources.getDeviceRepository(), harmonyHome, nestHome, hueHome, mqttHome, udpSender);
+ theHueMulator = new HueMulator(bridgeSettings.getBridgeSettingsDescriptor(), theResources.getDeviceRepository(), harmonyHome, nestHome, hueHome, mqttHome, hassHome, udpSender);
theHueMulator.setupServer();
// wait for the sparkjava initialization of the rest api classes to be complete
awaitInitialization();
diff --git a/src/main/java/com/bwssystems/HABridge/api/CallItem.java b/src/main/java/com/bwssystems/HABridge/api/CallItem.java
index aca1c7e..89383d6 100644
--- a/src/main/java/com/bwssystems/HABridge/api/CallItem.java
+++ b/src/main/java/com/bwssystems/HABridge/api/CallItem.java
@@ -1,7 +1,9 @@
package com.bwssystems.HABridge.api;
+import com.google.gson.JsonElement;
+
public class CallItem {
- private String item;
+ private JsonElement item;
private Integer count;
private Integer delay;
private String type;
@@ -23,12 +25,12 @@ public class CallItem {
this.filterIPs = filterIPs;
}
- public String getItem() {
+ public JsonElement getItem() {
return item;
}
- public void setItem(String anitem) {
- item = anitem;
+ public void setItem(JsonElement item) {
+ this.item = item;
}
public Integer getCount() {
diff --git a/src/main/java/com/bwssystems/HABridge/api/CallItemDeserializer.java b/src/main/java/com/bwssystems/HABridge/api/CallItemDeserializer.java
index c6e5ef7..39f6ddc 100644
--- a/src/main/java/com/bwssystems/HABridge/api/CallItemDeserializer.java
+++ b/src/main/java/com/bwssystems/HABridge/api/CallItemDeserializer.java
@@ -14,11 +14,16 @@ public class CallItemDeserializer implements JsonDeserializer {
JsonObject jsonObj = json.getAsJsonObject();
JsonElement jsonElem;
jsonElem = jsonObj.get("item");
- aCallItem.setItem(jsonElem.getAsString());
+ aCallItem.setItem(jsonElem);
jsonElem = jsonObj.get("delay");
aCallItem.setDelay(jsonElem.getAsInt());
jsonElem = jsonObj.get("count");
aCallItem.setCount(jsonElem.getAsInt());
+ jsonElem = jsonObj.get("type");
+ aCallItem.setType(jsonElem.getAsString());
+ jsonElem = jsonObj.get("filterIPs");
+ aCallItem.setFilterIPs(jsonElem.getAsString());
+
return aCallItem;
}
diff --git a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java
index af0d9e9..9e1078a 100644
--- a/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java
+++ b/src/main/java/com/bwssystems/HABridge/hue/HueMulator.java
@@ -23,6 +23,9 @@ import com.bwssystems.harmony.ButtonPress;
import com.bwssystems.harmony.HarmonyHandler;
import com.bwssystems.harmony.HarmonyHome;
import com.bwssystems.harmony.RunActivity;
+import com.bwssystems.hass.HassCommand;
+import com.bwssystems.hass.HassHome;
+import com.bwssystems.hass.HomeAssistant;
import com.bwssystems.hue.HueDeviceIdentifier;
import com.bwssystems.hue.HueErrorStringSet;
import com.bwssystems.hue.HueHome;
@@ -101,6 +104,7 @@ public class HueMulator implements HueErrorStringSet {
private Nest theNest;
private HueHome myHueHome;
private MQTTHome mqttHome;
+ private HassHome hassHome;
private HttpClient httpClient;
private CloseableHttpClient httpclientSSL;
private SSLContext sslcontext;
@@ -114,7 +118,7 @@ public class HueMulator implements HueErrorStringSet {
// private Gson callItemGson;
public HueMulator(BridgeSettingsDescriptor theBridgeSettings, DeviceRepository aDeviceRepository,
- HarmonyHome theHarmonyHome, NestHome aNestHome, HueHome aHueHome, MQTTHome aMqttHome,
+ HarmonyHome theHarmonyHome, NestHome aNestHome, HueHome aHueHome, MQTTHome aMqttHome, HassHome aHassHome,
UDPDatagramSender aUdpDatagramSender) {
httpClient = HttpClients.createDefault();
// Trust own CA and all self-signed certs
@@ -142,6 +146,10 @@ public class HueMulator implements HueErrorStringSet {
this.mqttHome = aMqttHome;
else
this.mqttHome = null;
+ if (theBridgeSettings.isValidHass())
+ this.hassHome = aHassHome;
+ else
+ this.hassHome = null;
bridgeSettings = theBridgeSettings;
theUDPDatagramSender = aUdpDatagramSender;
hueUser = null;
@@ -1054,14 +1062,45 @@ public class HueMulator implements HueErrorStringSet {
+ "\",\"description\": \"Should not get here, no mqtt brokers configured\", \"parameter\": \"/lights/"
+ lightId + "state\"}}]";
+ }
+ } else if (callItems[i].getType() != null && callItems[i].getType().trim().equalsIgnoreCase(DeviceMapTypes.HASS_DEVICE[DeviceMapTypes.typeIndex])) {
+ log.debug("executing HUE api request to send message to HomeAssistant: " + url);
+ if (hassHome != null) {
+ HassCommand hassCommand = new Gson().fromJson(callItems[i].getItem(), HassCommand.class);
+ HomeAssistant homeAssistant = hassHome.getHomeAssistant(hassCommand.getHassName());
+ if (homeAssistant == null) {
+ log.warn("Should not get here, no HomeAssistants available");
+ responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
+ + "\",\"description\": \"Should not get here, no HiomeAssistant clients available\", \"parameter\": \"/lights/"
+ + lightId + "state\"}}]";
+ }
+ for (int x = 0; x < setCount; x++) {
+ if (x > 0 || i > 0) {
+ Thread.sleep(theDelay);
+ }
+ if (callItems[i].getDelay() != null && callItems[i].getDelay() > 0)
+ theDelay = callItems[i].getDelay();
+ else
+ theDelay = bridgeSettings.getButtonsleep();
+ log.debug("calling HomeAssistant: " + hassCommand.getHassName() + " - "
+ + hassCommand.getEntityId() + " - " + hassCommand.getState() + " - " + hassCommand.getBri()
+ + " - iteration: " + String.valueOf(i) + " - count: " + String.valueOf(x));
+ homeAssistant.callCommand(hassCommand);
+ }
+ } else {
+ log.warn("Should not get here, no HomeAssistant clients configured");
+ responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
+ + "\",\"description\": \"Should not get here, no HomeAssistants configured\", \"parameter\": \"/lights/"
+ + lightId + "state\"}}]";
+
}
} 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().contains("exec://"))
- intermediate = callItems[i].getItem().substring(callItems[i].getItem().indexOf("://") + 3);
+ if (callItems[i].getItem().getAsString().contains("exec://"))
+ intermediate = callItems[i].getItem().getAsString().substring(callItems[i].getItem().getAsString().indexOf("://") + 3);
else
- intermediate = callItems[i].getItem();
+ intermediate = callItems[i].getItem().getAsString();
for (int x = 0; x < setCount; x++) {
if (x > 0 || i > 0) {
Thread.sleep(theDelay);
@@ -1090,10 +1129,10 @@ public class HueMulator implements HueErrorStringSet {
else
theDelay = bridgeSettings.getButtonsleep();
try {
- if (callItems[i].getItem().contains("udp://")
- || callItems[i].getItem().contains("tcp://")) {
- String intermediate = callItems[i].getItem()
- .substring(callItems[i].getItem().indexOf("://") + 3);
+ if (callItems[i].getItem().getAsString().contains("udp://")
+ || callItems[i].getItem().getAsString().contains("tcp://")) {
+ String intermediate = callItems[i].getItem().getAsString()
+ .substring(callItems[i].getItem().getAsString().indexOf("://") + 3);
String hostPortion = intermediate.substring(0, intermediate.indexOf('/'));
String theUrlBody = intermediate.substring(intermediate.indexOf('/') + 1);
String hostAddr = null;
@@ -1116,12 +1155,12 @@ public class HueMulator implements HueErrorStringSet {
false);
sendData = theUrlBody.getBytes();
}
- if (callItems[i].getItem().contains("udp://")) {
- log.debug("executing HUE api request to UDP: " + callItems[i].getItem());
+ if (callItems[i].getItem().getAsString().contains("udp://")) {
+ log.debug("executing HUE api request to UDP: " + callItems[i].getItem().getAsString());
theUDPDatagramSender.sendUDPResponse(new String(sendData), IPAddress,
Integer.parseInt(port));
- } else if (callItems[i].getItem().contains("tcp://")) {
- log.debug("executing HUE api request to TCP: " + callItems[i].getItem());
+ } else if (callItems[i].getItem().getAsString().contains("tcp://")) {
+ log.debug("executing HUE api request to TCP: " + callItems[i].getItem().getAsString());
Socket dataSendSocket = new Socket(IPAddress, Integer.parseInt(port));
DataOutputStream outToClient = new DataOutputStream(
dataSendSocket.getOutputStream());
@@ -1129,9 +1168,9 @@ public class HueMulator implements HueErrorStringSet {
outToClient.flush();
dataSendSocket.close();
}
- } else if (callItems[i].getItem().contains("exec://")) {
- String intermediate = callItems[i].getItem()
- .substring(callItems[i].getItem().indexOf("://") + 3);
+ } else if (callItems[i].getItem().getAsString().contains("exec://")) {
+ String intermediate = callItems[i].getItem().getAsString()
+ .substring(callItems[i].getItem().getAsString().indexOf("://") + 3);
String anError = doExecRequest(intermediate,
calculateIntensity(state, theStateChanges, stateHasBri, stateHasBriInc),
lightId);
@@ -1142,9 +1181,9 @@ public class HueMulator implements HueErrorStringSet {
} else {
log.debug("executing HUE api request to Http "
+ (device.getHttpVerb() == null ? "GET" : device.getHttpVerb()) + ": "
- + callItems[i].getItem());
+ + callItems[i].getItem().getAsString());
- String anUrl = replaceIntensityValue(callItems[i].getItem(),
+ String anUrl = replaceIntensityValue(callItems[i].getItem().getAsString(),
calculateIntensity(state, theStateChanges, stateHasBri, stateHasBriInc), false);
String body;
if (stateHasBri || stateHasBriInc)
@@ -1171,7 +1210,7 @@ public class HueMulator implements HueErrorStringSet {
}
} catch (Exception e) {
log.warn("Change device state, Could not send data for network request: "
- + callItems[i].getItem() + " with Message: " + e.getMessage());
+ + callItems[i].getItem().getAsString() + " with Message: " + e.getMessage());
responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
+ "\",\"description\": \"Error on calling out to device\", \"parameter\": \"/lights/"
+ lightId + "state\"}}]";
diff --git a/src/main/java/com/bwssystems/hass/HassCommand.java b/src/main/java/com/bwssystems/hass/HassCommand.java
new file mode 100644
index 0000000..c00613b
--- /dev/null
+++ b/src/main/java/com/bwssystems/hass/HassCommand.java
@@ -0,0 +1,33 @@
+package com.bwssystems.hass;
+
+public class HassCommand {
+ private String entityId;
+ private String hassName;
+ private String state;
+ private Integer bri;
+ public String getEntityId() {
+ return entityId;
+ }
+ public void setEntityId(String entityId) {
+ this.entityId = entityId;
+ }
+ public String getHassName() {
+ return hassName;
+ }
+ public void setHassName(String hassName) {
+ this.hassName = hassName;
+ }
+ public String getState() {
+ return state;
+ }
+ public void setState(String state) {
+ this.state = state;
+ }
+ public Integer getBri() {
+ return bri;
+ }
+ public void setBri(Integer bri) {
+ this.bri = bri;
+ }
+
+}
diff --git a/src/main/java/com/bwssystems/hass/HassHome.java b/src/main/java/com/bwssystems/hass/HassHome.java
index 88a7dc5..30a5b5b 100644
--- a/src/main/java/com/bwssystems/hass/HassHome.java
+++ b/src/main/java/com/bwssystems/hass/HassHome.java
@@ -15,9 +15,13 @@ import com.bwssystems.HABridge.NamedIP;
public class HassHome {
private static final Logger log = LoggerFactory.getLogger(HassHome.class);
private Map hassMap;
+ private Boolean validHass;
public HassHome(BridgeSettingsDescriptor bridgeSettings) {
super();
+ validHass = bridgeSettings.isValidHass();
+ if(!validHass)
+ return;
hassMap = new HashMap();
if(!bridgeSettings.isValidHass())
return;
@@ -33,8 +37,25 @@ public class HassHome {
}
}
+ public HomeAssistant getHomeAssistant(String aName) {
+ if(!validHass)
+ return null;
+ HomeAssistant aHomeAssistant;
+ if(aName == null || aName.equals("")) {
+ aHomeAssistant = null;
+ log.debug("Cannot get HomeAssistant for name as it is empty.");
+ }
+ else {
+ aHomeAssistant = hassMap.get(aName);
+ log.debug("Retrieved a HomeAssistant for name: " + aName);
+ }
+ return aHomeAssistant;
+ }
+
public List getDevices() {
- log.debug("consolidating devices for hues");
+ log.debug("consolidating devices for hass");
+ if(!validHass)
+ return null;
List theResponse = null;
Iterator keys = hassMap.keySet().iterator();
List deviceList = new ArrayList();
diff --git a/src/main/java/com/bwssystems/hass/HomeAssistant.java b/src/main/java/com/bwssystems/hass/HomeAssistant.java
index 72ed904..225d586 100644
--- a/src/main/java/com/bwssystems/hass/HomeAssistant.java
+++ b/src/main/java/com/bwssystems/hass/HomeAssistant.java
@@ -1,30 +1,56 @@
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.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;
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();
hassAddress = addressName;
}
@@ -36,13 +62,38 @@ public class HomeAssistant {
this.hassAddress = hassAddress;
}
+ public Boolean callCommand(HassCommand aCommand) {
+ log.debug("calling HomeAssistant: " + aCommand.getHassName() + " - "
+ + aCommand.getEntityId() + " - " + aCommand.getState() + " - " + aCommand.getBri());
+ String aUrl = "http://" + hassAddress.getIp() + ":" + hassAddress.getPort() + "/api/services/" + aCommand.getEntityId().substring(0, aCommand.getEntityId().indexOf("."));
+ String aBody = "{\"entity_id\":\"" + aCommand.getEntityId() + "\"";
+ NameValue[] headers = null;
+ if(hassAddress.getPassword() != null && !hassAddress.getPassword().isEmpty()) {
+ headers = new Gson().fromJson("{\"name\":\"x-ha-access\",\"value\":\"" + hassAddress.getPassword() + "\"}", NameValue[].class);
+ }
+ if(aCommand.getState().equalsIgnoreCase("on")) {
+ aUrl = aUrl + "/turn_on";
+ if(aCommand.getBri() != null && aCommand.getBri() > 0)
+ aBody = aBody + ",\"state\":\"on\",\"attributes\":{\"brightness\":" + aCommand.getBri() + "}}";
+ else
+ aBody = aBody + "}";
+ }
+ else {
+ aUrl = aUrl + "/turn_off";
+ aBody = aBody + "}";
+ }
+ String theData = doHttpRequest(aUrl, HttpPost.METHOD_NAME, "application/json", aBody, headers);
+ log.debug("call Command return is: <" + theData + ">");
+ return true;
+ }
+
public List getDevices() {
List theDeviceStates = null;
State[] theHassStates;
String theUrl = null;
String theData;
theUrl = "http://" + hassAddress.getIp() + ":" + hassAddress.getPort() + "/api/states";
- theData = doHttpGETRequest(theUrl);
+ theData = 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);
@@ -58,21 +109,88 @@ public class HomeAssistant {
return theDeviceStates;
}
- // This function executes the url against the hass
- 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;
- }
+ // 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;
+ }
}
diff --git a/src/main/resources/public/scripts/app.js b/src/main/resources/public/scripts/app.js
index 04c5b3b..388ed6b 100644
--- a/src/main/resources/public/scripts/app.js
+++ b/src/main/resources/public/scripts/app.js
@@ -1811,8 +1811,8 @@ app.controller('MQTTController', function ($scope, $location, $http, bridgeServi
var currentOff = $scope.device.offUrl;
if( $scope.device.mapType == "mqttMessage") {
$scope.device.mapId = $scope.device.mapId + "-" + mqtttopic;
- $scope.device.onUrl = currentOn.substr(0, currentOn.indexOf("]")) + ",{\"clientId\":\"" + mqttbroker.clientId + "\",\"topic\":\"" + mqtttopic + "\",\"message\":\"" + mqttmessage + "\"}]";
- $scope.device.offUrl = currentOff.substr(0, currentOff.indexOf("]")) + ",{\"clientId\":\"" + mqttbroker.clientId + "\",\"topic\":\"" + mqtttopic + "\",\"message\":\"" + mqttmessage + "\"}]";
+ $scope.device.onUrl = currentOn.substr(0, currentOn.indexOf("]")) + ",{\"item\":{\"clientId\":\"" + mqttbroker.clientId + "\",\"topic\":\"" + mqtttopic + "\",\"message\":\"" + mqttmessage + "\"},\"type\":\"mqttMessage\"}]";
+ $scope.device.offUrl = currentOff.substr(0, currentOff.indexOf("]")) + ",{\"item\":{\"clientId\":\"" + mqttbroker.clientId + "\",\"topic\":\"" + mqtttopic + "\",\"message\":\"" + mqttmessage + "\"},\"type\":\"mqttMessage\"}]";
}
else if ($scope.device.mapType == null || $scope.device.mapType == "") {
bridgeService.clearDevice();
@@ -1821,8 +1821,8 @@ app.controller('MQTTController', function ($scope, $location, $http, bridgeServi
$scope.device.name = mqttbroker.clientId + mqtttopic;
$scope.device.mapType = "mqttMessage";
$scope.device.mapId = mqttbroker.clientId + "-" + mqtttopic;
- $scope.device.onUrl = "[{\"clientId\":\"" + mqttbroker.clientId + "\",\"topic\":\"" + mqtttopic + "\",\"message\":\"" + mqttmessage + "\"}]";
- $scope.device.offUrl = "[{\"clientId\":\"" + mqttbroker.clientId + "\",\"topic\":\"" + mqtttopic + "\",\"message\":\"" + mqttmessage + "\"}]";
+ $scope.device.onUrl = "[{\"item\":{\"clientId\":\"" + mqttbroker.clientId + "\",\"topic\":\"" + mqtttopic + "\",\"message\":\"" + mqttmessage + "\"},\"type\":\"mqttMessage\"}]";
+ $scope.device.offUrl = "[{\"item\":{\"clientId\":\"" + mqttbroker.clientId + "\",\"topic\":\"" + mqtttopic + "\",\"message\":\"" + mqttmessage + "\"},\"type\":\"mqttMessage\"}]";
}
};
@@ -1875,14 +1875,16 @@ app.controller('HassController', function ($scope, $location, $http, bridgeServi
};
$scope.buildDeviceUrls = function (hassdevice, dim_control) {
- bridgeService.clearDevice();
$scope.device = $scope.bridge.device;
+ var currentOn = $scope.device.onUrl;
+ var currentDim = $scope.device.dimUrl;
+ var currentOff = $scope.device.offUrl;
if( $scope.device.mapType == "hassDevice" ) {
$scope.device.mapId = $scope.device.mapId + "-" + hassdevice.deviceState.entity_id;
- $scope.device.onUrl = currentOn.substr(0, currentOn.indexOf("]")) + ",{\"item\":\"{\"entityId\":\"" + hassdevice.deviceState.entity_id + "\",\"state\":\"on\"}\"}]";
+ $scope.device.onUrl = currentOn.substr(0, currentOn.indexOf("]")) + ",{\"item\":{\"entityId\":\"" + hassdevice.deviceState.entity_id + "\",\"hassName\":\"" + hassdevice.hassname + "\",\"state\":\"on\"},\"type\":\"hassDevice\"}]";
if((dim_control.indexOf("byte") >= 0 || dim_control.indexOf("percent") >= 0 || dim_control.indexOf("math") >= 0))
- $scope.device.dimUrl = currentOn.substr(0, currentOn.indexOf("]")) + ",{\"item\":\"{\"entityId\":\"" + hassdevice.deviceState.entity_id + "\",\"state\":\"on\",\"bri\":\"" + dim_control + "\"}\"}]";
- $scope.device.offUrl = currentOff.substr(0, currentOff.indexOf("]")) + ",{\"item\":\"{\"entityId\":\"" + hassdevice.deviceState.entity_id + "\",\"state\":\"off\"}\"}]";
+ $scope.device.dimUrl = currentDim.substr(0, currentDim.indexOf("]")) + ",{\"item\":{\"entityId\":\"" + hassdevice.deviceState.entity_id + "\",\"hassName\":\"" + hassdevice.hassname + "\",\"state\":\"on\",\"bri\":\"" + dim_control + "\"},\"type\":\"hassDevice\"}]";
+ $scope.device.offUrl = currentOff.substr(0, currentOff.indexOf("]")) + ",{\"item\":{\"entityId\":\"" + hassdevice.deviceState.entity_id + "\",\"hassName\":\"" + hassdevice.hassname + "\",\"state\":\"off\"},\"type\":\"hassDevice\"}]";
}
else if ($scope.device.mapType == null || $scope.device.mapType == "") {
bridgeService.clearDevice();
@@ -1891,10 +1893,10 @@ app.controller('HassController', function ($scope, $location, $http, bridgeServi
$scope.device.name = hassdevice.deviceState.entity_id;
$scope.device.mapType = "hassDevice";
$scope.device.mapId = hassdevice.hassname + "-" + hassdevice.deviceState.entity_id;
- $scope.device.onUrl = "[{\"item\":\"{\"entityId\":\"" + hassdevice.deviceState.entity_id + "\",\"state\":\"on\"}\"}]";
+ $scope.device.onUrl = "[{\"item\":{\"entityId\":\"" + hassdevice.deviceState.entity_id + "\",\"hassName\":\"" + hassdevice.hassname + "\",\"state\":\"on\"},\"type\":\"hassDevice\"}]";
if((dim_control.indexOf("byte") >= 0 || dim_control.indexOf("percent") >= 0 || dim_control.indexOf("math") >= 0))
- $scope.device.dimUrl = "[{\"item\":\"{\"entityId\":\"" + hassdevice.deviceState.entity_id + "\",\"state\":\"on\",\"bri\":\"" + dim_control + "\"}\"}]";
- $scope.device.offUrl = "[{\"item\":\"{\"entityId\":\"" + hassdevice.deviceState.entity_id + "\",\"state\":\"off\"}\"}]";
+ $scope.device.dimUrl = "[{\"item\":{\"entityId\":\"" + hassdevice.deviceState.entity_id + "\",\"hassName\":\"" + hassdevice.hassname + "\",\"state\":\"on\",\"bri\":\"" + dim_control + "\"},\"type\":\"hassDevice\"}]";
+ $scope.device.offUrl = "[{\"item\":{\"entityId\":\"" + hassdevice.deviceState.entity_id + "\",\"hassName\":\"" + hassdevice.hassname + "\",\"state\":\"off\"},\"type\":\"hassDevice\"}]";
}
};
@@ -2006,7 +2008,7 @@ app.controller('HassController', function ($scope, $location, $http, bridgeServi
function () {
$scope.clearDevice();
bridgeService.viewDevices();
- bridgeService.viewhassdevices();
+ bridgeService.viewHassDevices();
},
function (error) {
bridgeService.displayWarn("Error adding device: " + $scope.device.name, error)
@@ -2019,11 +2021,9 @@ app.controller('HassController', function ($scope, $location, $http, bridgeServi
var devicesList = [];
for(var i = 0; i < $scope.bulk.devices.length; i++) {
for(var x = 0; x < bridgeService.state.hassdevices.length; x++) {
- if(bridgeService.state.hassdevices[x].hassdevicename == $scope.bulk.devices[i]) {
- if(bridgeService.state.hassdevices[x].hassdevicetype == "HVAC")
- $scope.buildHALAutoUrls(bridgeService.state.hassdevices[x]);
- else if(bridgeService.state.hassdevices[x].hassdevicetype == "HOME")
- $scope.buildHALHomeUrls(bridgeService.state.hassdevices[x]);
+ if(bridgeService.state.hassdevices[x].deviceName == $scope.bulk.devices[i]) {
+ if(bridgeService.state.hassdevices[x].domain == "climate")
+ $scope.buildHassAutoUrls(bridgeService.state.hassdevices[x]);
else
$scope.buildDeviceUrls(bridgeService.state.hassdevices[x],dim_control);
devicesList[i] = {
diff --git a/src/main/resources/public/views/system.html b/src/main/resources/public/views/system.html
index 29b7128..386a0a5 100644
--- a/src/main/resources/public/views/system.html
+++ b/src/main/resources/public/views/system.html
@@ -301,7 +301,7 @@
placeholder="8123">
|
+ placeholder="Home Assistant password (opt)">
|