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)">