diff --git a/README.md b/README.md index d95a6ec..e04b2ff 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ THe Harmony Hub Path looks like this: **FAQ: Please look here for the current FAQs! https://github.com/bwssytems/ha-bridge/wiki/HA-Bridge-FAQs** -In the cases of systems that require authorization and/or have API's that cannot be handled in the current method, a module may need to be built. The Harmony Hub is such a module and so is the Nest module. The Bridge has helpers to build devices for the gateway for the Logitech Harmony Hub, Vera, Vera Lite or Vera Edge, Nest and the ability to proxy all of your real Hue bridges behind this bridge. +In the cases of systems that require authorization and/or have API's that cannot be handled in the current method, a module may need to be built. The Harmony Hub is such a module and so is the Nest module. The Bridge has helpers to build devices for the gateway for the Logitech Harmony Hub, Vera, Vera Lite or Vera Edge, Nest, Somfy Tahoma and the ability to proxy all of your real Hue bridges behind this bridge. Alternatively the Bridge supports custom calls as well using http/https/udp and tcp such as the LimitlessLED/MiLight bulbs using the UDP protocol. Binary data is supported with UDP/TCP. @@ -239,7 +239,7 @@ The server defaults to running on port 80. To override what the default is, spec #### UPNP Response Port The upnp response port that will be used. The default is 50000. #### Vera Names and IP Addresses -Provide IP Addresses of your Veras that you want to utilize with the bridge. Also, give a meaningful name to each one so it is easy to decipher in the helper tab. When these names and IP's are given, the bridge will be able to control the devices or scenes by the call it receives and send it to the target Vera and device/scene you configure. +Provide IP Addresses of your Veras that you want to utilize with the bridge. Also, give a meaningful name to each one so it is easy to decipher in the helper tab. When these names and IP's are given, the bridge will be able to control the devices or scenes by the call it receives and send it to the target Vera and device/scene you configure. Note you have to 'turn on' a window to open it, and 'turn off' to close. #### Harmony Names and IP Addresses Provide IP Addresses of your Harmony Hubs that you want to utilize with the bridge. Also, give a meaningful name to each one so it is easy to decipher in the helper tab. When these names and IP's are given, the bridge will be able to control the activity or buttons by the call it receives and send it to the target Harmony Hub and activity/button you configure. Also, an option of webhook can be called when the activity changes on the harmony hub that will send an HTTP GET call to the the address of your choosing. This can contain the replacement variables of ${activity.id} and/or ${activity.label}. Example : http://192.168.0.1/activity/${activity.id}/${activity.label} OR http://hook?a=${activity.label} #### Hue Names and IP Addresses @@ -258,6 +258,10 @@ The user name of the home.nest.com account for the Nest user. This needs to be g The password for the user name of the home.nest.com account for the Nest user. This needs to be given if you are using the Nest features. #### Nest Temp Fahrenheit This setting allows the value being sent into the bridge to be interpreted as Fahrenheit or Celsius. The default is to have Fahrenheit. +#### Somfy Tahoma Username +The user name used to login to www.tahomalink.com. This needs to be provided if you're using the Somfy Tahoma features (for connecting to IO Homecontrol used by Velux among others). There is no need to give any IP address or host information as this contacts your cloud account +#### Somfy Tahoma Password +The password associated with the Somfy Tahoma username above #### Button Press/Call Item Loop Sleep Interval (ms) This setting is the time used in between button presses when there is multiple buttons in a button device. It also controls the time between multiple items in a custom device call. This is defaulted to 100ms and the number represents milliseconds (1000 milliseconds = 1 second). #### Log Messages to Buffer @@ -308,7 +312,7 @@ The Add/Edit tab will show you the fields to fill in for the above in a form, wh The format of the item can be the default HTTP request which executes the URLs formatted as `http://` as a GET. Other options to this are to select the HTTP Verb and add the data type and add a body that is passed with the request. Secure https is supported as well, just use `https://`. When using POST and PUT, you have the ability to specify the body that will be sent with the request as well as the application type for the http call. The valid device types are: "custom", "veraDevice", "veraScene", "harmonyActivity", "harmonyButton", "nestHomeAway", "nestThermoSet", "hueDevice", "halDevice", - "halButton", "halHome", "halThermoSet", "mqttMessage", "cmdDevice", "hassDevice", "tcpDevice", "udpDevice", "httpDevice", "domoticzDevice" + "halButton", "halHome", "halThermoSet", "mqttMessage", "cmdDevice", "hassDevice", "tcpDevice", "udpDevice", "httpDevice", "domoticzDevice", "somfyDevice" Filter Ip example: ``` diff --git a/src/main/java/com/bwssystems/HABridge/BridgeSettings.java b/src/main/java/com/bwssystems/HABridge/BridgeSettings.java index cc5e6e8..0097e3a 100644 --- a/src/main/java/com/bwssystems/HABridge/BridgeSettings.java +++ b/src/main/java/com/bwssystems/HABridge/BridgeSettings.java @@ -46,6 +46,7 @@ public class BridgeSettings extends BackupHandler { public void buildSettings() { String addressString = null; String theVeraAddress = null; + String theSomfyAddress = null; String theHarmonyAddress = null; String configFileProperty = System.getProperty("config.file"); if(configFileProperty == null) { @@ -103,6 +104,23 @@ public class BridgeSettings extends BackupHandler { } } theBridgeSettings.setHarmonyAddress(theHarmonyList); + + theSomfyAddress = System.getProperty("somfy.address"); + IpList theSomfyList = null; + if(theSomfyAddress != null) { + try { + theSomfyList = new Gson().fromJson(theSomfyAddress, IpList.class); + } catch (Exception e) { + try { + theSomfyList = new Gson().fromJson("{devices:[{name:default,ip:" + theSomfyAddress + "}]}", IpList.class); + } catch (Exception et) { + log.error("Cannot parse somfy.address, not set with message: " + e.getMessage(), e); + theSomfyList = null; + } + } + } + theBridgeSettings.setSomfyAddress(theSomfyList); + theBridgeSettings.setUpnpStrict(Boolean.parseBoolean(System.getProperty("upnp.strict", "true"))); theBridgeSettings.setTraceupnp(Boolean.parseBoolean(System.getProperty("trace.upnp", "false"))); theBridgeSettings.setButtonsleep(Integer.parseInt(System.getProperty("button.sleep", Configuration.DEFAULT_BUTTON_SLEEP))); @@ -148,6 +166,7 @@ public class BridgeSettings extends BackupHandler { theBridgeSettings.setMqttconfigured(theBridgeSettings.isValidMQTT()); theBridgeSettings.setHassconfigured(theBridgeSettings.isValidHass()); theBridgeSettings.setDomoticzconfigured(theBridgeSettings.isValidDomoticz()); + theBridgeSettings.setSomfyconfigured(theBridgeSettings.isValidSomfy()); // Lifx is either configured or not, so it does not need an update. if(serverPortOverride != null) theBridgeSettings.setServerPort(serverPortOverride); diff --git a/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java b/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java index 8836976..5cf4ffe 100644 --- a/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java +++ b/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java @@ -49,6 +49,9 @@ public class BridgeSettingsDescriptor { private String hubversion; private IpList domoticzaddress; private boolean domoticzconfigured; + private IpList somfyaddress; + private boolean somfyconfigured; + private boolean lifxconfigured; public BridgeSettingsDescriptor() { @@ -57,6 +60,7 @@ public class BridgeSettingsDescriptor { this.traceupnp = false; this.nestconfigured = false; this.veraconfigured = false; + this.somfyconfigured = false; this.harmonyconfigured = false; this.hueconfigured = false; this.halconfigured = false; @@ -102,9 +106,15 @@ public class BridgeSettingsDescriptor { public IpList getVeraAddress() { return veraaddress; } + public IpList getSomfyAddress() { + return somfyaddress; + } public void setVeraAddress(IpList veraAddress) { this.veraaddress = veraAddress; } + public void setSomfyAddress(IpList somfyAddress) { + this.somfyaddress = somfyAddress; + } public IpList getHarmonyAddress() { return harmonyaddress; } @@ -138,9 +148,15 @@ public class BridgeSettingsDescriptor { public boolean isVeraconfigured() { return veraconfigured; } + public boolean isSomfyconfigured() { + return somfyconfigured; + } public void setVeraconfigured(boolean veraconfigured) { this.veraconfigured = veraconfigured; } + public void setSomfyconfigured(boolean somfyconfigured) { + this.somfyconfigured = somfyconfigured; + } public boolean isHarmonyconfigured() { return harmonyconfigured; } @@ -344,6 +360,14 @@ public class BridgeSettingsDescriptor { return false; return true; } + public Boolean isValidSomfy() { + if(this.getSomfyAddress() == null || this.getSomfyAddress().getDevices().size() <= 0) + return false; + List devicesList = this.getSomfyAddress().getDevices(); + if(devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS)) + return false; + return true; + } public Boolean isValidLifx() { return this.isLifxconfigured(); } diff --git a/src/main/java/com/bwssystems/HABridge/DeviceMapTypes.java b/src/main/java/com/bwssystems/HABridge/DeviceMapTypes.java index 1ee8125..56a06a4 100644 --- a/src/main/java/com/bwssystems/HABridge/DeviceMapTypes.java +++ b/src/main/java/com/bwssystems/HABridge/DeviceMapTypes.java @@ -1,84 +1,86 @@ -package com.bwssystems.HABridge; - -import java.util.ArrayList; - -public class DeviceMapTypes { - - public final static String[] CUSTOM_DEVICE = { "custom", "Custom"}; - public final static String[] VERA_DEVICE = { "veraDevice", "Vera Device"}; - public final static String[] VERA_SCENE = { "veraScene", "Vera Scene"}; - public final static String[] HARMONY_ACTIVITY = { "harmonyActivity", "Harmony Activity"}; - public final static String[] HARMONY_BUTTON = { "harmonyButton", "Harmony Button"}; - public final static String[] NEST_HOMEAWAY = { "nestHomeAway", "Nest Home Status"}; - public final static String[] NEST_THERMO_SET = { "nestThermoSet", "Nest Thermostat"}; - public final static String[] HUE_DEVICE = { "hueDevice", "Hue Device"}; - public final static String[] HAL_DEVICE = { "halDevice", "HAL Device"}; - public final static String[] HAL_BUTTON = { "halButton", "HAL Button"}; - public final static String[] HAL_HOME = { "halHome", "HAL Home Status"}; - 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_COMPAT = { "exec", "Execute Script/Program"}; - public final static String[] CMD_DEVICE = { "cmdDevice", "Execute Command/Script/Program"}; - public final static String[] HASS_DEVICE = { "hassDevice", "HomeAssistant Device"}; - public final static String[] TCP_DEVICE = { "tcpDevice", "TCP Device"}; - public final static String[] TCP_DEVICE_COMPAT = { "TCP", "TCP Device"}; - public final static String[] UDP_DEVICE = { "udpDevice", "UDP Device"}; - public final static String[] UDP_DEVICE_COMPAT = { "UDP", "UDP Device"}; - public final static String[] HTTP_DEVICE = { "httpDevice", "HTTP Device"}; - public final static String[] DOMOTICZ_DEVICE = { "domoticzDevice", "Domoticz Device"}; - public final static String[] LIFX_DEVICE = { "lifxDevice", "LIFX Device"}; - - public final static int typeIndex = 0; - public final static int displayIndex = 1; - - ArrayList deviceMapTypes; - - public DeviceMapTypes() { - super(); - deviceMapTypes = new ArrayList(); - deviceMapTypes.add(CMD_DEVICE); - deviceMapTypes.add(DOMOTICZ_DEVICE); - deviceMapTypes.add(HAL_DEVICE); - deviceMapTypes.add(HAL_HOME); - deviceMapTypes.add(HAL_THERMO_SET); - deviceMapTypes.add(HAL_BUTTON); - deviceMapTypes.add(HARMONY_ACTIVITY); - deviceMapTypes.add(HARMONY_BUTTON); - deviceMapTypes.add(HASS_DEVICE); - deviceMapTypes.add(HTTP_DEVICE); - deviceMapTypes.add(HUE_DEVICE); - deviceMapTypes.add(LIFX_DEVICE); - deviceMapTypes.add(MQTT_MESSAGE); - deviceMapTypes.add(NEST_HOMEAWAY); - deviceMapTypes.add(NEST_THERMO_SET); - deviceMapTypes.add(TCP_DEVICE); - deviceMapTypes.add(UDP_DEVICE); - deviceMapTypes.add(VERA_DEVICE); - deviceMapTypes.add(VERA_SCENE); - } - public static int getTypeIndex() { - return typeIndex; - } - public static int getDisplayIndex() { - return displayIndex; - } - public ArrayList getDeviceMapTypes() { - return deviceMapTypes; - } - - public Boolean validateType(String type) { - if(type == null || type.trim().isEmpty()) - return false; - for(String[] mapType : deviceMapTypes) { - if(type.trim().contentEquals(mapType[typeIndex])) - return true; - } - if(type.trim().contentEquals(EXEC_DEVICE_COMPAT[typeIndex])) - return true; - if(type.trim().contentEquals(TCP_DEVICE_COMPAT[typeIndex])) - return true; - if(type.trim().contentEquals(UDP_DEVICE_COMPAT[typeIndex])) - return true; - return false; - } +package com.bwssystems.HABridge; + +import java.util.ArrayList; + +public class DeviceMapTypes { + + public final static String[] CUSTOM_DEVICE = { "custom", "Custom"}; + public final static String[] VERA_DEVICE = { "veraDevice", "Vera Device"}; + public final static String[] VERA_SCENE = { "veraScene", "Vera Scene"}; + public final static String[] HARMONY_ACTIVITY = { "harmonyActivity", "Harmony Activity"}; + public final static String[] HARMONY_BUTTON = { "harmonyButton", "Harmony Button"}; + public final static String[] NEST_HOMEAWAY = { "nestHomeAway", "Nest Home Status"}; + public final static String[] NEST_THERMO_SET = { "nestThermoSet", "Nest Thermostat"}; + public final static String[] HUE_DEVICE = { "hueDevice", "Hue Device"}; + public final static String[] HAL_DEVICE = { "halDevice", "HAL Device"}; + public final static String[] HAL_BUTTON = { "halButton", "HAL Button"}; + public final static String[] HAL_HOME = { "halHome", "HAL Home Status"}; + 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_COMPAT = { "exec", "Execute Script/Program"}; + public final static String[] CMD_DEVICE = { "cmdDevice", "Execute Command/Script/Program"}; + public final static String[] HASS_DEVICE = { "hassDevice", "HomeAssistant Device"}; + public final static String[] TCP_DEVICE = { "tcpDevice", "TCP Device"}; + public final static String[] TCP_DEVICE_COMPAT = { "TCP", "TCP Device"}; + public final static String[] UDP_DEVICE = { "udpDevice", "UDP Device"}; + public final static String[] UDP_DEVICE_COMPAT = { "UDP", "UDP Device"}; + public final static String[] HTTP_DEVICE = { "httpDevice", "HTTP Device"}; + public final static String[] DOMOTICZ_DEVICE = { "domoticzDevice", "Domoticz Device"}; + public final static String[] SOMFY_DEVICE = { "somfyDevice", "Somfy Device"}; + public final static String[] LIFX_DEVICE = { "lifxDevice", "LIFX Device"}; + + public final static int typeIndex = 0; + public final static int displayIndex = 1; + + ArrayList deviceMapTypes; + + public DeviceMapTypes() { + super(); + deviceMapTypes = new ArrayList(); + deviceMapTypes.add(CMD_DEVICE); + deviceMapTypes.add(DOMOTICZ_DEVICE); + deviceMapTypes.add(HAL_DEVICE); + deviceMapTypes.add(HAL_HOME); + deviceMapTypes.add(HAL_THERMO_SET); + deviceMapTypes.add(HAL_BUTTON); + deviceMapTypes.add(HARMONY_ACTIVITY); + deviceMapTypes.add(HARMONY_BUTTON); + deviceMapTypes.add(HASS_DEVICE); + deviceMapTypes.add(HTTP_DEVICE); + deviceMapTypes.add(HUE_DEVICE); + deviceMapTypes.add(LIFX_DEVICE); + deviceMapTypes.add(MQTT_MESSAGE); + deviceMapTypes.add(NEST_HOMEAWAY); + deviceMapTypes.add(NEST_THERMO_SET); + deviceMapTypes.add(TCP_DEVICE); + deviceMapTypes.add(UDP_DEVICE); + deviceMapTypes.add(VERA_DEVICE); + deviceMapTypes.add(VERA_SCENE); + deviceMapTypes.add(SOMFY_DEVICE); + } + public static int getTypeIndex() { + return typeIndex; + } + public static int getDisplayIndex() { + return displayIndex; + } + public ArrayList getDeviceMapTypes() { + return deviceMapTypes; + } + + public Boolean validateType(String type) { + if(type == null || type.trim().isEmpty()) + return false; + for(String[] mapType : deviceMapTypes) { + if(type.trim().contentEquals(mapType[typeIndex])) + return true; + } + if(type.trim().contentEquals(EXEC_DEVICE_COMPAT[typeIndex])) + return true; + if(type.trim().contentEquals(TCP_DEVICE_COMPAT[typeIndex])) + return true; + if(type.trim().contentEquals(UDP_DEVICE_COMPAT[typeIndex])) + return true; + return false; + } } \ No newline at end of file diff --git a/src/main/java/com/bwssystems/HABridge/HomeManager.java b/src/main/java/com/bwssystems/HABridge/HomeManager.java index b11c76a..099a807 100644 --- a/src/main/java/com/bwssystems/HABridge/HomeManager.java +++ b/src/main/java/com/bwssystems/HABridge/HomeManager.java @@ -15,6 +15,7 @@ import com.bwssystems.HABridge.plugins.http.HTTPHome; import com.bwssystems.HABridge.plugins.hue.HueHome; import com.bwssystems.HABridge.plugins.lifx.LifxHome; import com.bwssystems.HABridge.plugins.mqtt.MQTTHome; +import com.bwssystems.HABridge.plugins.somfy.SomfyHome; import com.bwssystems.HABridge.plugins.tcp.TCPHome; import com.bwssystems.HABridge.plugins.udp.UDPHome; import com.bwssystems.HABridge.plugins.vera.VeraHome; @@ -88,6 +89,10 @@ public class HomeManager { aHome = new DomoticzHome(bridgeSettings); homeList.put(DeviceMapTypes.DOMOTICZ_DEVICE[DeviceMapTypes.typeIndex], aHome); resourceList.put(DeviceMapTypes.DOMOTICZ_DEVICE[DeviceMapTypes.typeIndex], aHome); + //setup the Somfy configuration if available + aHome = new SomfyHome(bridgeSettings); + homeList.put(DeviceMapTypes.SOMFY_DEVICE[DeviceMapTypes.typeIndex], aHome); + resourceList.put(DeviceMapTypes.SOMFY_DEVICE[DeviceMapTypes.typeIndex], aHome); //setup the Lifx configuration if available aHome = new LifxHome(bridgeSettings); resourceList.put(DeviceMapTypes.LIFX_DEVICE[DeviceMapTypes.typeIndex], aHome); diff --git a/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java b/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java index e4bb6ca..8a93bc8 100644 --- a/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java +++ b/src/main/java/com/bwssystems/HABridge/devicemanagmeent/DeviceResource.java @@ -260,7 +260,13 @@ public class DeviceResource { return homeManager.findResource(DeviceMapTypes.LIFX_DEVICE[DeviceMapTypes.typeIndex]).getItems(DeviceMapTypes.LIFX_DEVICE[DeviceMapTypes.typeIndex]); }, new JsonTransformer()); - get (API_CONTEXT + "/map/types", "application/json", (request, response) -> { + get (API_CONTEXT + "/somfy/devices", "application/json", (request, response) -> { + log.debug("Get somfy devices"); + response.status(HttpStatus.SC_OK); + return homeManager.findResource(DeviceMapTypes.SOMFY_DEVICE[DeviceMapTypes.typeIndex]).getItems(DeviceMapTypes.SOMFY_DEVICE[DeviceMapTypes.typeIndex]); + }, new JsonTransformer()); + + get (API_CONTEXT + "/map/types", "application/json", (request, response) -> { log.debug("Get map types"); return new DeviceMapTypes().getDeviceMapTypes(); }, new JsonTransformer()); diff --git a/src/main/java/com/bwssystems/HABridge/plugins/somfy/SomfyDevice.java b/src/main/java/com/bwssystems/HABridge/plugins/somfy/SomfyDevice.java new file mode 100644 index 0000000..e29743a --- /dev/null +++ b/src/main/java/com/bwssystems/HABridge/plugins/somfy/SomfyDevice.java @@ -0,0 +1,67 @@ +package com.bwssystems.HABridge.plugins.somfy; + +public class SomfyDevice { + private String id; + private String room; + private String category; + private String somfyname; + private String name; + private String deviceUrl; + private String deviceType; + + public void setId(String id) { + this.id = id; + } + + public String getId() { + return id; + } + + public void setRoom(String room) { + this.room = room; + } + + public String getRoom() { + return room; + } + + public void setCategory(String category) { + this.category = category; + } + + public String getCategory() { + return category; + } + + public void setSomfyname(String somfyname) { + this.somfyname = somfyname; + } + + public String getSomfyname() { + return somfyname; + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setDeviceUrl(String deviceUrl) { + this.deviceUrl = deviceUrl; + } + + public String getDeviceUrl() { + return deviceUrl; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public String getDeviceType() { + return deviceType; + } +} diff --git a/src/main/java/com/bwssystems/HABridge/plugins/somfy/SomfyHome.java b/src/main/java/com/bwssystems/HABridge/plugins/somfy/SomfyHome.java new file mode 100644 index 0000000..9073bb1 --- /dev/null +++ b/src/main/java/com/bwssystems/HABridge/plugins/somfy/SomfyHome.java @@ -0,0 +1,118 @@ +package com.bwssystems.HABridge.plugins.somfy; + +import com.bwssystems.HABridge.BridgeSettingsDescriptor; +import com.bwssystems.HABridge.DeviceMapTypes; +import com.bwssystems.HABridge.Home; +import com.bwssystems.HABridge.NamedIP; +import com.bwssystems.HABridge.api.CallItem; +import com.bwssystems.HABridge.dao.DeviceDescriptor; +import com.bwssystems.HABridge.hue.MultiCommandUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.HashMap; + +/** + * Support for Somfy Tahoma hub which allows control of IO Homecontrol devices such as Velux windows. + * Currently supports 'turn on' for open window, and 'turn off' for close. + * + * Known issues: + * //TODO - Fix bug on UI where bulk update seems to add the single device twice if 'update' is clicked (this is a general bug with Vera too I think) + * Enhancements: + * //TODO - support 'dimming' for partial window opening. + * + */ +public class SomfyHome implements Home { + private static final Logger log = LoggerFactory.getLogger(SomfyHome.class); + private Map somfys; + private Boolean validSomfy; + + public SomfyHome(BridgeSettingsDescriptor bridgeSettings) { + createHome(bridgeSettings); + + } + + public SomfyInfo getSomfyHandler(String somfyName) { + return somfys.get(somfyName); + } + + public List getDevices() { + log.debug("consolidating devices for somfy"); + Iterator keys = somfys.keySet().iterator(); + ArrayList deviceList = new ArrayList<>(); + while(keys.hasNext()) { + String key = keys.next(); + List devices = somfys.get(key).getSomfyDevices(); + deviceList.addAll(devices); + } + return deviceList; + } + + @Override + public Object getItems(String type) { + if(validSomfy) { + if(type.equalsIgnoreCase(DeviceMapTypes.SOMFY_DEVICE[DeviceMapTypes.typeIndex])) + return getDevices(); + } + return null; + } + + @Override + public String deviceHandler(CallItem anItem, MultiCommandUtil aMultiUtil, String lightId, int intensity, Integer targetBri, Integer targetBriInc, DeviceDescriptor device, String body) { + String responseString = null; + if (!validSomfy) { + log.warn("Should not get here, no somfy hub available"); + responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + + "\",\"description\": \"Should not get here, no somfy hub available\", \"parameter\": \"/lights/" + + lightId + "state\"}}]"; + } else { + if (anItem.getType() != null && anItem.getType().trim().equalsIgnoreCase(DeviceMapTypes.SOMFY_DEVICE[DeviceMapTypes.typeIndex])) { + + log.debug("executing HUE api request to change activity to Somfy: " + anItem.getItem().toString()); + String jsonToPost = anItem.getItem().toString(); + + SomfyInfo somfyHandler = getSomfyHandler(device.getTargetDevice()); + if(somfyHandler == null) { + log.warn("Should not get here, no Somfy configured"); + responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + + "\",\"description\": \"Should not get here, no somfy configured\", \"parameter\": \"/lights/" + + lightId + "state\"}}]"; + } else { + try { + somfyHandler.execApply(jsonToPost); + } catch (Exception e) { + log.warn("Error posting request to Somfy"); + responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId + + "\",\"description\": \"Error posting request to SomfyTahoma\", \"parameter\": \"/lights/" + lightId + "state\"}}]"; + } + + } + } + } + return responseString; + } + + @Override + public Home createHome(BridgeSettingsDescriptor bridgeSettings) { + validSomfy = bridgeSettings.isValidSomfy(); + log.info("Somfy Home created." + (validSomfy ? "" : " No Somfys configured.")); + if(validSomfy) { + somfys = new HashMap<>(); + Iterator theList = bridgeSettings.getSomfyAddress().getDevices().iterator(); + while (theList.hasNext()) { + NamedIP aSomfy = theList.next(); + somfys.put(aSomfy.getName(), new SomfyInfo(aSomfy, aSomfy.getName())); + } + } + return this; + } + + @Override + public void closeHome() { + somfys = null; + } +} diff --git a/src/main/java/com/bwssystems/HABridge/plugins/somfy/SomfyInfo.java b/src/main/java/com/bwssystems/HABridge/plugins/somfy/SomfyInfo.java new file mode 100644 index 0000000..cd70fc9 --- /dev/null +++ b/src/main/java/com/bwssystems/HABridge/plugins/somfy/SomfyInfo.java @@ -0,0 +1,116 @@ +package com.bwssystems.HABridge.plugins.somfy; + +import com.bwssystems.HABridge.NamedIP; +import com.bwssystems.HABridge.api.NameValue; +import com.bwssystems.HABridge.plugins.http.HTTPHandler; +import com.bwssystems.HABridge.plugins.somfy.jsonschema2pojo.getsetup.Device; +import com.bwssystems.HABridge.plugins.somfy.jsonschema2pojo.getsetup.GetSetup; +import com.google.gson.Gson; +import org.apache.http.NameValuePair; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.message.BasicNameValuePair; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.List; + + +public class SomfyInfo { + private static final Logger log = LoggerFactory.getLogger(SomfyInfo.class); + private final String somfyName; + private final NamedIP namedIP; + private HTTPHandler httpClient; + private static final String CONNECT_HOST = "https://www.tahomalink.com/"; + private static final String BASE_URL = CONNECT_HOST + "enduser-mobile-web/externalAPI/"; + private static final String BASE_URL_ENDUSER = CONNECT_HOST + "enduser-mobile-web/enduserAPI/"; + + public SomfyInfo(NamedIP namedIP, String somfyName) { + super(); + this.somfyName = somfyName; + this.namedIP = namedIP; + } + + private void initHttpClient() throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException { + if(httpClient==null) { + httpClient = new HTTPHandler(); + } + } + + + + public List getSomfyDevices() { + + List somfyDevices = new ArrayList<>(); + try { + login(namedIP.getUsername(), namedIP.getPassword()); + GetSetup setupData = getSetup(); + for(Device device : setupData.getSetup().getDevices()) { + somfyDevices.add(mapDeviceToSomfyDevice(device)); + } + } catch (Exception e) { + log.error("Could not get Somfy devices", e); + } + return somfyDevices; + } + + + public void login(String username, String password) throws Exception { + + initHttpClient(); + NameValue[] httpHeader = getHttpHeaders(); + List nvps = new ArrayList(); + nvps.add(new BasicNameValuePair("userId", username)); + nvps.add(new BasicNameValuePair("userPassword", password)); + log.debug("Making SOMFY http login call"); + UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(nvps); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + urlEncodedFormEntity.writeTo(bos); + String body = bos.toString(); + String response = httpClient.doHttpRequest(BASE_URL + "json/login",HttpPost.METHOD_NAME, "application/x-www-form-urlencoded", body,httpHeader); + log.debug(response); + } + + private NameValue[] getHttpHeaders() { + NameValue userAgentHeader = new NameValue(); + userAgentHeader.setName("User-Agent"); + userAgentHeader.setValue("mine"); + return new NameValue[]{userAgentHeader}; + } + + public GetSetup getSetup() throws IOException { + NameValue[] httpHeader = getHttpHeaders(); + log.info("Making SOMFY http setup call"); + String response = httpClient.doHttpRequest(BASE_URL + "json/getSetup", HttpGet.METHOD_NAME, "", "", httpHeader ); + log.debug(response); + GetSetup setupData = new Gson().fromJson(response, GetSetup.class); + return setupData; + } + + public void execApply(String jsonToPost) throws Exception { + login(namedIP.getUsername(), namedIP.getPassword()); + log.info("Making SOMFY http exec call"); + String response = httpClient.doHttpRequest(BASE_URL_ENDUSER + "exec/apply", HttpPost.METHOD_NAME, "application/json;charset=UTF-8", jsonToPost, getHttpHeaders()); + log.info(response); + } + + + protected SomfyDevice mapDeviceToSomfyDevice(Device device) { + SomfyDevice somfyDevice = new SomfyDevice(); + somfyDevice.setId(device.getOid()); + somfyDevice.setCategory(device.getUiClass()); + somfyDevice.setRoom(""); + somfyDevice.setSomfyname(somfyName); + somfyDevice.setName(device.getLabel()); + somfyDevice.setDeviceUrl(device.getDeviceURL()); + somfyDevice.setDeviceType(device.getWidget()); + return somfyDevice; + } + +} diff --git a/src/main/java/com/bwssystems/HABridge/plugins/somfy/jsonschema2pojo/getsetup/Device.java b/src/main/java/com/bwssystems/HABridge/plugins/somfy/jsonschema2pojo/getsetup/Device.java new file mode 100644 index 0000000..b61aaee --- /dev/null +++ b/src/main/java/com/bwssystems/HABridge/plugins/somfy/jsonschema2pojo/getsetup/Device.java @@ -0,0 +1,69 @@ + +package com.bwssystems.HABridge.plugins.somfy.jsonschema2pojo.getsetup; + +import java.util.List; +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class Device { + + @SerializedName("label") + @Expose + private String label; + @SerializedName("deviceURL") + @Expose + private String deviceURL; + @SerializedName("widget") + @Expose + private String widget; + @SerializedName("oid") + @Expose + private String oid; + @SerializedName("uiClass") + @Expose + private String uiClass; + + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public String getDeviceURL() { + return deviceURL; + } + + public void setDeviceURL(String deviceURL) { + this.deviceURL = deviceURL; + } + + + public String getWidget() { + return widget; + } + + public void setWidget(String widget) { + this.widget = widget; + } + + + public String getOid() { + return oid; + } + + public void setOid(String oid) { + this.oid = oid; + } + + public String getUiClass() { + return uiClass; + } + + public void setUiClass(String uiClass) { + this.uiClass = uiClass; + } + +} diff --git a/src/main/java/com/bwssystems/HABridge/plugins/somfy/jsonschema2pojo/getsetup/GetSetup.java b/src/main/java/com/bwssystems/HABridge/plugins/somfy/jsonschema2pojo/getsetup/GetSetup.java new file mode 100644 index 0000000..0478b58 --- /dev/null +++ b/src/main/java/com/bwssystems/HABridge/plugins/somfy/jsonschema2pojo/getsetup/GetSetup.java @@ -0,0 +1,21 @@ + +package com.bwssystems.HABridge.plugins.somfy.jsonschema2pojo.getsetup; + +import java.util.List; +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class GetSetup { + + @SerializedName("setup") + @Expose + private Setup setup; + + public Setup getSetup() { + return setup; + } + + public void setSetup(Setup setup) { + this.setup = setup; + } +} diff --git a/src/main/java/com/bwssystems/HABridge/plugins/somfy/jsonschema2pojo/getsetup/Setup.java b/src/main/java/com/bwssystems/HABridge/plugins/somfy/jsonschema2pojo/getsetup/Setup.java new file mode 100644 index 0000000..90f76dd --- /dev/null +++ b/src/main/java/com/bwssystems/HABridge/plugins/somfy/jsonschema2pojo/getsetup/Setup.java @@ -0,0 +1,35 @@ + +package com.bwssystems.HABridge.plugins.somfy.jsonschema2pojo.getsetup; + +import java.util.List; +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class Setup { + + @SerializedName("id") + @Expose + private String id; + @SerializedName("devices") + @Expose + private List devices = null; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + + +} diff --git a/src/main/java/com/bwssystems/HABridge/plugins/somfy/jsonschema2pojo/getsetup/generationConfig b/src/main/java/com/bwssystems/HABridge/plugins/somfy/jsonschema2pojo/getsetup/generationConfig new file mode 100644 index 0000000..2f2dbf8 --- /dev/null +++ b/src/main/java/com/bwssystems/HABridge/plugins/somfy/jsonschema2pojo/getsetup/generationConfig @@ -0,0 +1,19 @@ +http://www.jsonschema2pojo.org/ + +The json was: +{"setup":{"creationTime":1481970091000,"lastUpdateTime":1481970091000,"id":"SETUP-1202-4393-9834","location":{"creationTime":1481970091000,"lastUpdateTime":1481970412000,"city":"London","country":"Switzerland","postalCode":"SW15 1QR","addressLine1":"5 Abbotstone Road","addressLine2":"","timezone":"Europe/Zurich","longitude":-0.1262,"latitude":51.5001,"twilightMode":3,"twilightAngle":"CIVIL","twilightCity":"london","summerSolsticeDuskMinutes":1290,"winterSolsticeDuskMinutes":990,"twilightOffsetEnabled":true,"dawnOffset":0,"duskOffset":0},"gateways":[{"gatewayId":"1202-4393-9834","type":29,"subType":2,"placeOID":"6bf877ec-bce0-4243-86d6-ec8526c97efe","alive":true,"timeReliable":true,"connectivity":{"status":"OK","protocolVersion":"16"},"upToDate":true,"mode":"ACTIVE","functions":"INTERNET_AUTHORIZATION,SCENARIO_DOWNLOAD,SCENARIO_AUTO_LAUNCHING,SCENARIO_TELECO_LAUNCHING,INTERNET_UPLOAD,INTERNET_UPDATE,TRIGGERS_SENSORS"}],"devices":[{"creationTime":1481970091000,"lastUpdateTime":1481970091000,"label":"Touch button","deviceURL":"internal://1202-4393-9834/pod/0","shortcut":false,"controllableName":"internal:PodV2Component","metadata":"{\"tahoma\":{\"touchButtonFlag\":true}}","definition":{"commands":[{"commandName":"getName","nparams":0},{"commandName":"refreshBatteryStatus","nparams":0},{"commandName":"refreshPodMode","nparams":0},{"commandName":"setLightingLedPodMode","nparams":1},{"commandName":"setPodLedOff","nparams":0},{"commandName":"setPodLedOn","nparams":0}],"events":[],"states":[{"eventBased":false,"values":["pressed","stop"],"type":"DiscreteState","qualifiedName":"core:CyclicButtonState"},{"eventBased":false,"type":"DataState","qualifiedName":"core:NameState"},{"eventBased":false,"type":"ContinuousState","qualifiedName":"internal:BatteryStatusState"},{"eventBased":false,"type":"ContinuousState","qualifiedName":"internal:LightingLedPodModeState"}],"dataProperties":[],"widgetName":"Pod","uiClass":"Pod","qualifiedName":"internal:PodV2Component","type":"ACTUATOR"},"states":[{"name":"core:NameState","type":3,"value":"Box"},{"name":"internal:BatteryStatusState","type":3,"value":"no"},{"name":"internal:LightingLedPodModeState","type":3,"value":"1"}],"attributes":[],"available":true,"enabled":true,"placeOID":"6bf877ec-bce0-4243-86d6-ec8526c97efe","widget":"Pod","type":1,"oid":"1b8766cd-298c-4bfe-95ad-26b4cc8f0ae5","uiClass":"Pod"},{"creationTime":1481978106000,"lastUpdateTime":1481978106000,"label":"Corridor Window","deviceURL":"io://1202-4393-9834/1867135","shortcut":false,"controllableName":"io:WindowOpenerVeluxIOComponent","definition":{"commands":[{"commandName":"close","nparams":0},{"commandName":"delayedStopIdentify","nparams":1},{"commandName":"getName","nparams":0},{"commandName":"identify","nparams":0},{"commandName":"open","nparams":0},{"commandName":"setClosure","nparams":1},{"commandName":"setName","nparams":1},{"commandName":"startIdentify","nparams":0},{"commandName":"stopIdentify","nparams":0},{"commandName":"wink","nparams":1}],"events":[],"states":[{"eventBased":false,"type":"ContinuousState","qualifiedName":"core:ClosureState"},{"eventBased":false,"type":"DataState","qualifiedName":"core:NameState"},{"eventBased":false,"values":["closed","open"],"type":"DiscreteState","qualifiedName":"core:OpenClosedState"},{"eventBased":false,"type":"ContinuousState","qualifiedName":"core:PriorityLockTimerState"},{"eventBased":false,"type":"ContinuousState","qualifiedName":"core:RSSILevelState"},{"eventBased":false,"values":["available","unavailable"],"type":"DiscreteState","qualifiedName":"core:StatusState"},{"eventBased":false,"values":["comfortLevel1","comfortLevel2","comfortLevel3","comfortLevel4","environmentProtection","humanProtection","userLevel1","userLevel2"],"type":"DiscreteState","qualifiedName":"io:PriorityLockLevelState"},{"eventBased":false,"values":["LSC","SAAC","SFC","UPS","externalGateway","localUser","myself","rain","security","timer","user","wind"],"type":"DiscreteState","qualifiedName":"io:PriorityLockOriginatorState"}],"dataProperties":[{"value":"500","qualifiedName":"core:identifyInterval"}],"widgetName":"PositionableTiltedWindow","uiClass":"Window","qualifiedName":"io:WindowOpenerVeluxIOComponent","type":"ACTUATOR"},"states":[{"name":"core:NameState","type":3,"value":"Corridor Window"},{"name":"core:StatusState","type":3,"value":"unavailable"},{"name":"core:RSSILevelState","type":2,"value":100.0},{"name":"core:ClosureState","type":1,"value":100},{"name":"core:OpenClosedState","type":3,"value":"closed"}],"attributes":[],"available":false,"enabled":true,"placeOID":"05badcc3-b8f3-4562-9c03-ac5f39e976f0","widget":"PositionableTiltedWindow","type":1,"oid":"4e589092-0aec-4bff-9881-3711117fb432","uiClass":"Window"},{"creationTime":1481978106000,"lastUpdateTime":1481978106000,"label":"Bathroom Window","deviceURL":"io://1202-4393-9834/8711888","shortcut":false,"controllableName":"io:WindowOpenerVeluxIOComponent","definition":{"commands":[{"commandName":"close","nparams":0},{"commandName":"delayedStopIdentify","nparams":1},{"commandName":"getName","nparams":0},{"commandName":"identify","nparams":0},{"commandName":"open","nparams":0},{"commandName":"setClosure","nparams":1},{"commandName":"setName","nparams":1},{"commandName":"startIdentify","nparams":0},{"commandName":"stopIdentify","nparams":0},{"commandName":"wink","nparams":1}],"events":[],"states":[{"eventBased":false,"type":"ContinuousState","qualifiedName":"core:ClosureState"},{"eventBased":false,"type":"DataState","qualifiedName":"core:NameState"},{"eventBased":false,"values":["closed","open"],"type":"DiscreteState","qualifiedName":"core:OpenClosedState"},{"eventBased":false,"type":"ContinuousState","qualifiedName":"core:PriorityLockTimerState"},{"eventBased":false,"type":"ContinuousState","qualifiedName":"core:RSSILevelState"},{"eventBased":false,"values":["available","unavailable"],"type":"DiscreteState","qualifiedName":"core:StatusState"},{"eventBased":false,"values":["comfortLevel1","comfortLevel2","comfortLevel3","comfortLevel4","environmentProtection","humanProtection","userLevel1","userLevel2"],"type":"DiscreteState","qualifiedName":"io:PriorityLockLevelState"},{"eventBased":false,"values":["LSC","SAAC","SFC","UPS","externalGateway","localUser","myself","rain","security","timer","user","wind"],"type":"DiscreteState","qualifiedName":"io:PriorityLockOriginatorState"}],"dataProperties":[{"value":"500","qualifiedName":"core:identifyInterval"}],"widgetName":"PositionableTiltedWindow","uiClass":"Window","qualifiedName":"io:WindowOpenerVeluxIOComponent","type":"ACTUATOR"},"states":[{"name":"core:NameState","type":3,"value":"Bathroom Window"},{"name":"core:StatusState","type":3,"value":"available"},{"name":"core:RSSILevelState","type":2,"value":100.0},{"name":"core:ClosureState","type":1,"value":100},{"name":"core:OpenClosedState","type":3,"value":"closed"}],"attributes":[],"available":true,"enabled":true,"placeOID":"73104664-4ceb-4831-bc5d-97af8cb45144","widget":"PositionableTiltedWindow","type":1,"oid":"e6d0639b-a587-4bd6-aa38-56d6d16df3c5","uiClass":"Window"}],"zones":[],"resellerDelegationType":"NEVER","rootPlace":{"creationTime":1481970091000,"lastUpdateTime":1481978338000,"label":"House","type":200,"oid":"6bf877ec-bce0-4243-86d6-ec8526c97efe","subPlaces":[{"creationTime":1481979193000,"lastUpdateTime":1481979193000,"label":"terrace","type":106,"metadata":"{\"tahoma\":{\"position\":-0.25,\"decor\":[{\"id\":\"tree2\",\"type\":1002,\"offset\":0}]}}","oid":"ee20af13-2e41-4938-a458-a6b6b9417035","subPlaces":[]},{"creationTime":1481979193000,"lastUpdateTime":1481979193000,"label":"2nd floor","type":103,"oid":"849b8684-ba45-47f3-8ccb-57292ef6beef","subPlaces":[{"creationTime":1481979193000,"lastUpdateTime":1481979193000,"label":"Bathroom Upstairs","type":8,"metadata":"{\"tahoma\":{\"order\":2}}","oid":"73104664-4ceb-4831-bc5d-97af8cb45144","subPlaces":[]},{"creationTime":1481979193000,"lastUpdateTime":1481979193000,"label":"Study","type":16,"metadata":"{\"tahoma\":{\"order\":1}}","oid":"35bc314c-4608-49ab-8a0f-6b5ced4b03e3","subPlaces":[]},{"creationTime":1481979193000,"lastUpdateTime":1481979193000,"label":"Bedroom Alice","type":6,"metadata":"{\"tahoma\":{\"order\":3}}","oid":"a5d69ff0-bf92-4d38-bb32-c1dcba36149f","subPlaces":[]},{"creationTime":1481979193000,"lastUpdateTime":1481979193000,"label":"Corridor Top","type":23,"metadata":"{\"tahoma\":{\"order\":0}}","oid":"05badcc3-b8f3-4562-9c03-ac5f39e976f0","subPlaces":[]}]}]},"features":[{"name":"tahoma-basic-plus","source":"GATEWAY_TYPE"}]},"events":[]} + +package: com.bwssystems.HABridge.plugins.somfy.jsonschema2pojo.getsetup +Class name: GetSetup + +Source type: JSON + +Annotation style: Gson + +Boxes checked: + Use long integers + Use double numbers + Include getters and setters + Allow additional properties + +Then manually removed all the unused methods so we have minimal json->pojo representation. \ No newline at end of file diff --git a/src/main/resources/public/scripts/app.js b/src/main/resources/public/scripts/app.js index 7a4cb83..7b73e04 100644 --- a/src/main/resources/public/scripts/app.js +++ b/src/main/resources/public/scripts/app.js @@ -44,6 +44,11 @@ app.config (function ($locationProvider, $routeProvider) { controller: 'HassController' }).when ('/domoticzdevices', { templateUrl: 'views/domoticzdevice.html', + controller: 'DomoticzController' + }).when('/somfydevices', { + templateUrl: 'views/somfydevice.html', + controller: 'SomfyController' + }).otherwise ({ controller: 'DomoticzController' }).when ('/lifxdevices', { templateUrl: 'views/lifxdevice.html', @@ -75,7 +80,7 @@ String.prototype.replaceAll = function (search, replace) app.service ('bridgeService', function ($http, $window, ngToast) { var self = this; - this.state = {base: "./api/devices", bridgelocation: ".", systemsbase: "./system", huebase: "./api", configs: [], backups: [], devices: [], device: {}, mapandid: [], type: "", settings: [], myToastMsg: [], logMsgs: [], loggerInfo: [], mapTypes: [], olddevicename: "", logShowAll: false, isInControl: false, showVera: false, showHarmony: false, showNest: false, showHue: false, showHal: false, showMqtt: false, showHass: false, showDomoticz: false, showLifx: false, habridgeversion: ""}; + this.state = {base: "./api/devices", bridgelocation: ".", systemsbase: "./system", huebase: "./api", configs: [], backups: [], devices: [], device: {}, mapandid: [], type: "", settings: [], myToastMsg: [], logMsgs: [], loggerInfo: [], mapTypes: [], olddevicename: "", logShowAll: false, isInControl: false, showVera: false, showHarmony: false, showNest: false, showHue: false, showHal: false, showMqtt: false, showHass: false, showDomoticz: false, showSomfy: false, showLifx: false, habridgeversion: ""}; this.displayWarn = function(errorTitle, error) { var toastContent = errorTitle; @@ -272,6 +277,11 @@ app.service ('bridgeService', function ($http, $window, ngToast) { return; } + this.updateShowSomfy = function () { + this.state.showSomfy = self.state.settings.somfyconfigured; + return; + } + this.updateShowLifx = function () { this.state.showLifx = self.state.settings.lifxconfigured; return; @@ -289,6 +299,7 @@ app.service ('bridgeService', function ($http, $window, ngToast) { self.updateShowMqtt(); self.updateShowHass(); self.updateShowDomoticz(); + self.updateShowSomfy(); self.updateShowLifx(); }, function (error) { @@ -471,6 +482,20 @@ app.service ('bridgeService', function ($http, $window, ngToast) { ); }; + this.viewSomfyDevices = function () { + if(!this.state.showSomfy) + return; + return $http.get(this.state.base + "/somfy/devices").then( + function (response) { + self.state.somfydevices = response.data; + }, + function (error) { + self.displayWarn("Get Somfy Devices Error: ", error); + } + ); + }; + + this.viewLifxDevices = function () { if (!this.state.showLifx) return; @@ -1050,6 +1075,25 @@ app.controller ('SystemController', function ($scope, $location, $http, $window, } } }; + $scope.addSomfytoSettings = function (newsomfyname, newsomfyip, newsomfyusername, newsomfypassword) { + if($scope.bridge.settings.somfyaddress == null) { + $scope.bridge.settings.somfyaddress = { devices: [] }; + } + var newSomfy = {name: newsomfyname, ip: newsomfyip, username: newsomfyusername, password: newsomfypassword } + $scope.bridge.settings.somfyaddress.devices.push(newSomfy); + $scope.newsomfyname = null; + $scope.newsomfyip = null; + $scope.newsomfyusername = null; + $scope.newsomfypassword = null; + }; + $scope.removeSomfytoSettings = function (somfyname, somfyip) { + for(var i = $scope.bridge.settings.somfyaddress.devices.length - 1; i >= 0; i--) { + if($scope.bridge.settings.somfyaddress.devices[i].name === somfyname && $scope.bridge.settings.somfyaddress.devices[i].ip === somfyip) { + $scope.bridge.settings.somfyaddress.devices.splice(i, 1); + } + } + }; + $scope.bridgeReinit = function () { bridgeService.reinit(); }; @@ -2426,6 +2470,134 @@ app.controller('LifxController', function ($scope, $location, $http, bridgeServi }; }); +app.controller('SomfyController', function ($scope, $location, $http, bridgeService, ngDialog) { + $scope.bridge = bridgeService.state; + $scope.device = bridgeService.state.device; + $scope.device_dim_control = ""; + $scope.bulk = { devices: [] }; + $scope.selectAll = false; + $scope.somfy = {base: "http://", port: "3480", id: ""}; + bridgeService.viewDevices(); //Needs this if you're navigating to the 'somfy' page directly without going to the home page first.. + bridgeService.viewSomfyDevices(); + $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; + $scope.buttonsVisible = false; + $scope.comparatorUniqueId = bridgeService.compareUniqueId; + + $scope.clearDevice = function () { + bridgeService.clearDevice(); + $scope.device = bridgeService.state.device; + }; + + $scope.buildDeviceUrls = function (somfydevice, dim_control, buildonly) { + //TODO - support partial window opening - add back 'dim_control' second param in here, and in somfydevice.html + dimpayload = ""; + onpayload = "{\"label\":\"Label that is ignored probably\",\"actions\":[{\"deviceURL\":\""+ somfydevice.deviceUrl+"\",\"commands\":[{\"name\":\"open\",\"parameters\":[]}]}]}"; + offpayload = "{\"label\":\"Label that is ignored probably\",\"actions\":[{\"deviceURL\":\""+ somfydevice.deviceUrl+"\",\"commands\":[{\"name\":\"close\",\"parameters\":[]}]}]}"; + + bridgeService.buildUrls(onpayload, dimpayload, offpayload, true, somfydevice.id, somfydevice.name, somfydevice.somfyname, "switch", "somfyDevice", null, null); + $scope.device = bridgeService.state.device; + if (!buildonly) { + bridgeService.editNewDevice($scope.device); + $location.path('/editdevice'); + } + }; + + + $scope.bulkAddDevices = function(dim_control) { + var devicesList = []; + $scope.clearDevice(); + for(var i = 0; i < $scope.bulk.devices.length; i++) { + for(var x = 0; x < bridgeService.state.somfydevices.length; x++) { + if(bridgeService.state.somfydevices[x].id === $scope.bulk.devices[i]) { + $scope.buildDeviceUrls(bridgeService.state.somfydevices[x],dim_control, true); + devicesList[i] = { + name: $scope.device.name, + mapId: $scope.device.mapId, + mapType: $scope.device.mapType, + deviceType: $scope.device.deviceType, + targetDevice: $scope.device.targetDevice, + onUrl: $scope.device.onUrl, + dimUrl: $scope.device.dimUrl, + offUrl: $scope.device.offUrl, + headers: $scope.device.headers, + httpVerb: $scope.device.httpVerb, + contentType: $scope.device.contentType, + contentBody: $scope.device.contentBody, + contentBodyDim: $scope.device.contentBodyDim, + contentBodyOff: $scope.device.contentBodyOff + }; + $scope.clearDevice(); + } + } + } + bridgeService.bulkAddDevice(devicesList).then( + function () { + $scope.clearDevice(); + bridgeService.viewDevices(); + bridgeService.viewSomfyDevices(); + }, + function (error) { + bridgeService.displayWarn("Error adding Somfy devices in bulk.", error) + } + ); + $scope.bulk = { devices: [] }; + $scope.selectAll = false; + }; + + $scope.toggleSelection = function toggleSelection(deviceId) { + var idx = $scope.bulk.devices.indexOf(deviceId); + + // is currently selected + if (idx > -1) { + $scope.bulk.devices.splice(idx, 1); + if($scope.bulk.devices.length === 0 && $scope.selectAll) + $scope.selectAll = false; + } + + // is newly selected + else { + $scope.bulk.devices.push(deviceId); + $scope.selectAll = true; + } + }; + + $scope.toggleSelectAll = function toggleSelectAll() { + if($scope.selectAll) { + $scope.selectAll = false; + $scope.bulk = { devices: [] }; + } + else { + $scope.selectAll = true; + for(var x = 0; x < bridgeService.state.somfydevices.length; x++) { + if($scope.bulk.devices.indexOf(bridgeService.state.somfydevices[x]) < 0 && !bridgeService.findDeviceByMapId(bridgeService.state.somfydevices[x].id, bridgeService.state.somfydevices[x].somfyname, "somfyDevice")) + $scope.bulk.devices.push(bridgeService.state.somfydevices[x].id); + } + } + }; + + $scope.toggleButtons = function () { + $scope.buttonsVisible = !$scope.buttonsVisible; + if($scope.buttonsVisible) + $scope.imgButtonsUrl = "glyphicon glyphicon-minus"; + else + $scope.imgButtonsUrl = "glyphicon glyphicon-plus"; + }; + + $scope.deleteDevice = function (device) { + $scope.bridge.device = device; + ngDialog.open({ + template: 'deleteDialog', + controller: 'DeleteDialogCtrl', + className: 'ngdialog-theme-default' + }); + }; + + $scope.editDevice = function (device) { + bridgeService.editDevice(device); + $location.path('/editdevice'); + }; +}); + app.controller('EditController', function ($scope, $location, $http, bridgeService) { bridgeService.viewMapTypes(); $scope.bridge = bridgeService.state; @@ -2717,6 +2889,23 @@ app.filter('configuredLifxItems', function (bridgeService) { } }); +app.filter('configuredSomfyDevices', function (bridgeService) { + return function(input) { + var out = []; + if(input === undefined || input === null || input.length === undefined) + return out; + for (var i = 0; i < input.length; i++) { + if(bridgeService.deviceContainsType(input[i], "somfyDevice")){ + out.push(input[i]); + } + } + return out; + } +}); + + + + app.controller('VersionController', function ($scope, bridgeService) { $scope.bridge = bridgeService.state; }); diff --git a/src/main/resources/public/views/configuration.html b/src/main/resources/public/views/configuration.html index e24e642..14dc9b4 100644 --- a/src/main/resources/public/views/configuration.html +++ b/src/main/resources/public/views/configuration.html @@ -1,145 +1,146 @@ - - - -
-
-

Current devices ({{bridge.devices.length}})

-
-
- -

- -

- - - - - - - - - - - - - - - - - - - - - - - - - -
RowIDNameTypeTargetInactiveNo StateActions
{{$index+1}}{{device.id}}{{device.name}}{{device.deviceType}}{{device.targetDevice}}{{device.inactive}}{{device.noState}} -

- - - - - -

-
-
-
-
-
-
-

- Bridge Device DB Backup -

-
-
-

Control your backups from this area. Use the default name by hitting backup or specify your own.

-
-
- - -
- -
- -
-
- - - - - - - - - - - -
FilenameActions
{{backup}} - - -
-
-
- - - + + + +
+
+

Current devices ({{bridge.devices.length}})

+
+
+ +

+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + +
RowIDNameTypeTargetInactiveNo StateActions
{{$index+1}}{{device.id}}{{device.name}}{{device.deviceType}}{{device.targetDevice}}{{device.inactive}}{{device.noState}} +

+ + + + + +

+
+
+
+
+
+
+

+ Bridge Device DB Backup +

+
+
+

Control your backups from this area. Use the default name by hitting backup or specify your own.

+
+
+ + +
+ +
+ +
+
+ + + + + + + + + + + +
FilenameActions
{{backup}} + + +
+
+
+ + + diff --git a/src/main/resources/public/views/domoticzdevice.html b/src/main/resources/public/views/domoticzdevice.html index 7629889..7eedd32 100644 --- a/src/main/resources/public/views/domoticzdevice.html +++ b/src/main/resources/public/views/domoticzdevice.html @@ -18,6 +18,7 @@
  • MQTT Messages
  • HomeAssistant Devices
  • +
  • Somfy Devices
  • LIFX Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/editdevice.html b/src/main/resources/public/views/editdevice.html index ea8df42..759b10b 100644 --- a/src/main/resources/public/views/editdevice.html +++ b/src/main/resources/public/views/editdevice.html @@ -20,6 +20,7 @@
  • HomeAssistant Devices
  • Domoticz Devices
  • +
  • Somfy Devices
  • LIFX Devices
  • diff --git a/src/main/resources/public/views/haldevice.html b/src/main/resources/public/views/haldevice.html index 38b2cd3..7d365e2 100644 --- a/src/main/resources/public/views/haldevice.html +++ b/src/main/resources/public/views/haldevice.html @@ -1,178 +1,179 @@ - - -
    -
    -

    HAL Device List - ({{bridge.haldevices.length}})

    -
    -
    -

    For any HAL Device, use the build action buttons - to generate the item addition information into the ha-bridge device and this will put you into the edit screen. Then - you can modify the name to anything you want that will be the keyword - for the Echo or Google Home. Also, you can go back to any helper tab and click a build - action button to add another item for a multi-command. After you are - done in the edit tab, click the 'Add Bridge Device' to finish that selection - setup. The 'Already Configured HAL Devices' list below will show what - is already setup for your HAL.

    -

    - Also, use this select menu for which type of dim control you would - like to be generated: -

    -

    Use the check boxes by the names to use the bulk addition - feature. Select your items and dim control type if wanted, then click - bulk add below. Your items will be added with on and off or dim and - off if selected with the name of the device from the HAL.

    - - - - - - - - - - - - - - - - - - - - - - -
    Row - NameCategoryHALOn ButtonOff ButtonBuild Actions
    {{$index+1}} - {{haldevice.haldevicename}}{{haldevice.haldevicetype}}{{haldevice.halname}} - - - - - - - -
      -
    • -

      - - - -

      -

      - - -

      -
    • -
    -
    -
    - -
    -
    -
    -
    -

    - Already Configured HAL Devices -

    -
    -
    - - - - - - - - - - - - - - - - - - - - - -
    RowNameCategoryHALMap IdActions
    {{$index+1}}{{device.name}}{{device.deviceType}}{{device.targetDevice}}{{device.mapId}} -

    - - -

    -
    -
    -
    -
    - + + +
    +
    +

    HAL Device List + ({{bridge.haldevices.length}})

    +
    +
    +

    For any HAL Device, use the build action buttons + to generate the item addition information into the ha-bridge device and this will put you into the edit screen. Then + you can modify the name to anything you want that will be the keyword + for the Echo or Google Home. Also, you can go back to any helper tab and click a build + action button to add another item for a multi-command. After you are + done in the edit tab, click the 'Add Bridge Device' to finish that selection + setup. The 'Already Configured HAL Devices' list below will show what + is already setup for your HAL.

    +

    + Also, use this select menu for which type of dim control you would + like to be generated: +

    +

    Use the check boxes by the names to use the bulk addition + feature. Select your items and dim control type if wanted, then click + bulk add below. Your items will be added with on and off or dim and + off if selected with the name of the device from the HAL.

    + + + + + + + + + + + + + + + + + + + + + + +
    Row + NameCategoryHALOn ButtonOff ButtonBuild Actions
    {{$index+1}} + {{haldevice.haldevicename}}{{haldevice.haldevicetype}}{{haldevice.halname}} + + + + + + + +
      +
    • +

      + + + +

      +

      + + +

      +
    • +
    +
    +
    + +
    +
    +
    +
    +

    + Already Configured HAL Devices +

    +
    +
    + + + + + + + + + + + + + + + + + + + + + +
    RowNameCategoryHALMap IdActions
    {{$index+1}}{{device.name}}{{device.deviceType}}{{device.targetDevice}}{{device.mapId}} +

    + + +

    +
    +
    +
    +
    + diff --git a/src/main/resources/public/views/harmonyactivity.html b/src/main/resources/public/views/harmonyactivity.html index a82a0c7..7666a8f 100644 --- a/src/main/resources/public/views/harmonyactivity.html +++ b/src/main/resources/public/views/harmonyactivity.html @@ -1,112 +1,113 @@ - - -
    -
    -

    Harmony Activity List

    -
    -
    -

    For any Harmony Activity, use the build action buttons - to generate the item addition information into the ha-bridge device and this will put you into the edit screen. - Then you can modify the name to anything you want that - will be the keyword for the Echo or Google Home. Also, you can go back to any helper tab and click a build - action button to add another item for a multi-command. After you are - done in the edit tab, click the 'Add Bridge Device' to - finish that selection setup. The 'Already Configured Activities' list - below will show what is already setup for your Harmony Hubs.

    - - - - - - - - - - - - - - - - - - - -
    RowNameIdHubBuild Actions
    {{$index+1}}{{harmonyactivity.activity.label}}{{harmonyactivity.activity.id}}{{harmonyactivity.hub}} - -
    -
    -
    -
    -
    -
    -

    - Already Configured Activities -

    -
    -
    - - - - - - - - - - - - - - - - - - -
    RowNameHubMap IdActions
    {{$index+1}}{{device.name}}{{device.targetDevice}}{{device.mapId}} -

    - - -

    -
    -
    -
    -
    - \ No newline at end of file diff --git a/src/main/resources/public/views/harmonydevice.html b/src/main/resources/public/views/harmonydevice.html index 6b01a15..a4f51d2 100644 --- a/src/main/resources/public/views/harmonydevice.html +++ b/src/main/resources/public/views/harmonydevice.html @@ -1,131 +1,132 @@ - - -
    -
    -

    Harmony Device List

    -
    -
    -

    For any Harmony Device and Buttons, use the - build action buttons - to generate the item addition information into the ha-bridge device and this will put you into the edit screen. Then you can modify the name - to anything you want that will be the keyword for the Echo or Google Home. Also, you can go back to any helper tab and click a build - action button to add another item for a multi-command. After you are - done in the edit tab, click the - 'Add Bridge Device' to finish that selection setup. The 'Already - Configured Harmony Buttons' list below will show what is already - setup for your Harmony Hubs.

    - - - - - - - - - - - - - - - - - - - - - - - -
    RowNameIdHubOn ButtonOff ButtonBuild Actions
    {{$index+1}}{{harmonydevice.device.label}}{{harmonydevice.device.id}}{{harmonydevice.hub}} - -
    -
    -
    -
    -
    -
    -

    - Already Configured Harmony Buttons -

    -
    -
    - - - - - - - - - - - - - - - - - - -
    RowNameHubHarmony Device-Button On-Button OffActions
    {{$index+1}}{{device.name}}{{device.targetDevice}}{{device.mapId}} -

    - - -

    -
    -
    -
    -
    - \ No newline at end of file diff --git a/src/main/resources/public/views/hassdevice.html b/src/main/resources/public/views/hassdevice.html index 1ff957d..c03084b 100644 --- a/src/main/resources/public/views/hassdevice.html +++ b/src/main/resources/public/views/hassdevice.html @@ -18,6 +18,7 @@
  • MQTT Messages
  • Domoticz Devices
  • +
  • Somfy Devices
  • LIFX Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/huedevice.html b/src/main/resources/public/views/huedevice.html index 7d9325c..222a977 100644 --- a/src/main/resources/public/views/huedevice.html +++ b/src/main/resources/public/views/huedevice.html @@ -1,127 +1,128 @@ - - -
    -
    -

    Hue Device List - ({{bridge.huedevices.length}})

    -
    -
    -

    For any Hue Device, use the build action buttons - to generate the item addition information into the ha-bridge device and this will put you into the edit screen. Then - you can modify the name to anything you want that will be the keyword - for the Echo or Google Home. Also, you can go back to any helper tab and click a build - action button to add another item for a multi-command. After you are - done in the edit tab, click the 'Add Bridge Device' to finish that selection - setup. The 'Already Configured Hue Devices' list below will show what - is already setup for your Hue.

    -

    Use the check boxes by the names to use the bulk addition - feature. Select your items, then click bulk add below. Your items - will be added with on, off and dim with the - name of the device from the Hue.

    - - - - - - - - - - - - - - - - - - -
    Row NameIdHueBuild Actions
    {{$index+1}} - {{huedevice.device.name}}{{huedevice.device.uniqueid}}{{huedevice.huename}} - -
    -
    - -
    -
    -
    -
    -

    - Already Configured Hue Devices -

    -
    -
    - - - - - - - - - - - - - - - - - - -
    RowNamehueMap IdActions
    {{$index+1}}{{device.name}}{{device.targetDevice}}{{device.mapId}} -

    - - -

    -
    -
    -
    -
    - + + +
    +
    +

    Hue Device List + ({{bridge.huedevices.length}})

    +
    +
    +

    For any Hue Device, use the build action buttons + to generate the item addition information into the ha-bridge device and this will put you into the edit screen. Then + you can modify the name to anything you want that will be the keyword + for the Echo or Google Home. Also, you can go back to any helper tab and click a build + action button to add another item for a multi-command. After you are + done in the edit tab, click the 'Add Bridge Device' to finish that selection + setup. The 'Already Configured Hue Devices' list below will show what + is already setup for your Hue.

    +

    Use the check boxes by the names to use the bulk addition + feature. Select your items, then click bulk add below. Your items + will be added with on, off and dim with the + name of the device from the Hue.

    + + + + + + + + + + + + + + + + + + +
    Row NameIdHueBuild Actions
    {{$index+1}} + {{huedevice.device.name}}{{huedevice.device.uniqueid}}{{huedevice.huename}} + +
    +
    + +
    +
    +
    +
    +

    + Already Configured Hue Devices +

    +
    +
    + + + + + + + + + + + + + + + + + + +
    RowNamehueMap IdActions
    {{$index+1}}{{device.name}}{{device.targetDevice}}{{device.mapId}} +

    + + +

    +
    +
    +
    +
    + diff --git a/src/main/resources/public/views/lifxdevice.html b/src/main/resources/public/views/lifxdevice.html index 465c557..583df49 100644 --- a/src/main/resources/public/views/lifxdevice.html +++ b/src/main/resources/public/views/lifxdevice.html @@ -12,6 +12,7 @@
  • MQTT Messages
  • HomeAssistant Devices
  • Domoticz Devices
  • +
  • Somfy Devices
  • Add/Edit
  • diff --git a/src/main/resources/public/views/logs.html b/src/main/resources/public/views/logs.html index a1939e9..c1d853c 100644 --- a/src/main/resources/public/views/logs.html +++ b/src/main/resources/public/views/logs.html @@ -1,89 +1,90 @@ - - -
    -
    -

    Log Messages

    -
    -
    -

    - -

    - - - - - - - - - - - - - - - - -
    TimeLevelMessageComponent
    {{logMessage.time}}{{logMessage.level}}{{logMessage.message}}{{logMessage.component}}
    -
    -
    -
    -
    -
    -

    - Logging Configuration -

    -
    -
    -

    - - Show All Loggers - {{bridge.logShowAll}} -

    - - - - - - - - - - - - - - -
    Log LevelComponentNew Log Level
    {{logInfo.logLevel.substr(0,logInfo.logLevel.indexOf("_"))}}{{logInfo.loggerName}}
    -
    -
    + + +
    +
    +

    Log Messages

    +
    +
    +

    + +

    + + + + + + + + + + + + + + + + +
    TimeLevelMessageComponent
    {{logMessage.time}}{{logMessage.level}}{{logMessage.message}}{{logMessage.component}}
    +
    +
    +
    +
    +
    +

    + Logging Configuration +

    +
    +
    +

    + + Show All Loggers + {{bridge.logShowAll}} +

    + + + + + + + + + + + + + + +
    Log LevelComponentNew Log Level
    {{logInfo.logLevel.substr(0,logInfo.logLevel.indexOf("_"))}}{{logInfo.loggerName}}
    +
    +
    \ No newline at end of file diff --git a/src/main/resources/public/views/mqttpublish.html b/src/main/resources/public/views/mqttpublish.html index 6fd06db..9fe47da 100644 --- a/src/main/resources/public/views/mqttpublish.html +++ b/src/main/resources/public/views/mqttpublish.html @@ -1,117 +1,118 @@ - - -
    -
    -

    MQTT Messages

    -
    -
    -

    For any MQTT Broker, use the - build action buttons - to generate the item addition information into the ha-bridge device and this will put you into the edit screen. - You can add topic and content in the text areas provided - then selecting the publish generation. Then you can modify the name - to anything you want that will be the keyword for the Echo or Google Home. Also, you can go back to any helper tab and click a build - action button to add another item for a multi-command. After you are - done in the edit tab, click the - 'Add Bridge Device' to finish that selection setup. The 'Already - Configured MQTT Publish messages' list below will show what is already - setup for your MQTT Brokers.

    - - - - - - - - - - - - - - - - - - - - - -
    RowClientIDIPTopicContentBuild Actions
    {{$index+1}}{{mqttbroker.clientId}}{{mqttbroker.ip}} - - - - - -
    -
    -
    -
    -
    -
    -

    - Already Configured MQTT Messages -

    -
    -
    - - - - - - - - - - - - - - - - - - -
    RowNameClientIDMap IdActions
    {{$index+1}}{{device.name}}{{device.targetDevice}}{{device.mapId}} -

    - - -

    -
    -
    -
    -
    - \ No newline at end of file diff --git a/src/main/resources/public/views/nestactions.html b/src/main/resources/public/views/nestactions.html index 59cdfbe..c91cff6 100644 --- a/src/main/resources/public/views/nestactions.html +++ b/src/main/resources/public/views/nestactions.html @@ -1,133 +1,134 @@ - - -
    -
    -

    Nest Items List

    -
    -
    -

    For any Nest Item, use the build action buttons - to generate the item addition information into the ha-bridge device and this will put you into the edit screen. Then - you can modify the name to anything you want that will be the keyword - for the Echo or Google Home. Also, you can go back to any helper tab and click a build - action button to add another item for a multi-command. After you are - done in the edit tab, click the 'Add Bridge Device' to finish that selection - setup. The 'Already Configured Nest Items' list below will show what - is already setup for your Nest.

    - - - - - - - - - - - - - - - - - - - -
    RowNameTypeLocationBuild Actions
    {{$index+1}}{{nestitem.name}}{{nestitem.type}}{{nestitem.location}} -
      -
    • - -
    • -
    • -

      - - - -

      -

      - - - -

      -
    • -
    -
    -
    -
    -
    -
    -
    -

    - Already Configured Nest Items -

    -
    -
    - - - - - - - - - - - - - - - - - - -
    RowNameLocationMap IdActions
    {{$index+1}}{{device.name}}{{device.targetDevice}}{{device.mapId}} -

    - - -

    -
    -
    -
    -
    - \ No newline at end of file diff --git a/src/main/resources/public/views/somfydevice.html b/src/main/resources/public/views/somfydevice.html new file mode 100644 index 0000000..7bdbc07 --- /dev/null +++ b/src/main/resources/public/views/somfydevice.html @@ -0,0 +1,143 @@ + + +
    +
    +

    Somfy Device List + ({{bridge.somfydevices.length}})

    +
    +
    +

    For any Somfy Device, use the build action buttons + to generate the item addition information into the ha-bridge device + and this will put you into the edit screen. Then + you can modify the name to anything you want that will be the keyword + for the Echo or Google Home. Also, you can go back to any helper tab and click a build + action button to add another item for a multi-command. After you are + done in the edit tab, click the 'Add Bridge Device' to finish that selection + setup. The 'Already Configured Somfy Devices' list below will show + what is already setup for your Somfy.

    + +

    Use the check boxes by the names to use the bulk addition + feature. Select your items, then click + bulk add below. Your items will be added with the name of the device from the Somfy Tahoma.

    +
    + + + + + + + + + + + + + + + + + + + + + + +
    Row NameIdCategoryRoomSomfyBuild Actions
    {{$index+1}} + {{somfydevice.name}}{{somfydevice.id}}{{somfydevice.category}}{{somfydevice.room}}{{somfydevice.somfyname}} + + +
    +
    + +
    +
    +
    +
    +

    + Already Configured Somfy Devices +

    +
    +
    + + + + + + + + + + + + + + + + + + +
    RowNameSomfyMap IdActions
    {{$index+1}}{{device.name}}{{device.targetDevice}}{{device.mapId}} +

    + + +

    +
    +
    +
    +
    + diff --git a/src/main/resources/public/views/system.html b/src/main/resources/public/views/system.html index 06fb374..7902872 100644 --- a/src/main/resources/public/views/system.html +++ b/src/main/resources/public/views/system.html @@ -19,6 +19,7 @@
  • MQTT Messages
  • HomeAssistant Devices
  • Domoticz Devices
  • +
  • Somfy Devices
  • LIFX Devices
  • Add/Edit
  • @@ -363,6 +364,46 @@ + + Somfy Names and IP Addresses + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameIP/hostnameUsernamePassword Manage
    {{somfy.name}}{{somfy.ip}}{{somfy.username}}*******
    + Nest Username -
  • Bridge Devices
  • -
  • Bridge Control
  • -
  • Logs
  • - -
  • Vera Scenes
  • -
  • Harmony Activities
  • -
  • Harmony Devices
  • -
  • Nest
  • -
  • Hue Devices
  • -
  • HAL Devices
  • -
  • MQTT Messages
  • -
  • HomeAssistant Devices
  • -
  • Domoticz Devices
  • -
  • LIFX Devices
  • -
  • Add/Edit
  • - - -
    -
    -

    Vera Device List - ({{bridge.veradevices.length}})

    -
    -
    -

    For any Vera Device, use the build action buttons - to generate the item addition information into the ha-bridge device - and this will put you into the edit screen. Then - you can modify the name to anything you want that will be the keyword - for the Echo or Google Home. Also, you can go back to any helper tab and click a build - action button to add another item for a multi-command. After you are - done in the edit tab, click the 'Add Bridge Device' to finish that selection - setup. The 'Already Configured Vera Devices' list below will show - what is already setup for your Vera.

    -

    - Also, use this select menu for which type of dim control you would - like to be generated: -

    -

    Use the check boxes by the names to use the bulk addition - feature. Select your items and dim control type if wanted, then click - bulk add below. Your items will be added with on and off or dim and - off if selected with the name of the device from the Vera.

    - - - - - - - - - - - - - - - - - - - - - - -
    Row NameIdCategoryRoomVeraBuild Actions
    {{$index+1}} - {{veradevice.name}}{{veradevice.id}}{{veradevice.category}}{{veradevice.room}}{{veradevice.veraname}} - -
    -
    - -
    -
    -
    -
    -

    - Already Configured Vera Devices -

    -
    -
    - - - - - - - - - - - - - - - - - - -
    RowNameVeraMap IdActions
    {{$index+1}}{{device.name}}{{device.targetDevice}}{{device.mapId}} -

    - - -

    -
    -
    -
    -
    - \ No newline at end of file diff --git a/src/main/resources/public/views/verascene.html b/src/main/resources/public/views/verascene.html index 70d8aba..e66ae06 100644 --- a/src/main/resources/public/views/verascene.html +++ b/src/main/resources/public/views/verascene.html @@ -1,112 +1,113 @@ - - -
    -
    -

    Vera Scene List

    -
    -
    -

    For any Vera Scene, use the build action buttons - to generate the item addition information into the ha-bridge device and this will put you into the edit screen. Then - you can modify the name to anything you want that will be the keyword - for the Echo or Google Home. Also, you can go back to any helper tab and click a build - action button to add another item for a multi-command. After you are - done in the edit tab, click the 'Add Bridge Device' to finish that selection - setup. The 'Already Configured Vera Scenes' list below will show what - is already setup for your Vera.

    - - - - - - - - - - - - - - - - - - - - - -
    RowNameIdRoomVeraBuild Actions
    {{$index+1}}{{verascene.name}}{{verascene.id}}{{verascene.room}}{{verascene.veraname}} - -
    -
    -
    -
    -
    -
    -

    - Already Configured Vera Scenes -

    -
    -
    - - - - - - - - - - - - - - - - - - -
    RowNameVeraMap IdActions
    {{$index+1}}{{device.name}}{{device.targetDevice}}{{device.mapId}} -

    - - -

    -
    -
    -
    -
    - \ No newline at end of file