mirror of
https://github.com/bwssytems/ha-bridge.git
synced 2025-12-19 16:41:53 +00:00
Compare commits
61 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
20dedec8ab | ||
|
|
580c037b1e | ||
|
|
77cb064d60 | ||
|
|
0e4319ea1d | ||
|
|
c61e623e23 | ||
|
|
669483f686 | ||
|
|
5a59747bc9 | ||
|
|
53ec096c95 | ||
|
|
8ccb768391 | ||
|
|
9d84e2a180 | ||
|
|
6a5fae583f | ||
|
|
8d15d0a0fb | ||
|
|
d4b8b70a83 | ||
|
|
a276f97776 | ||
|
|
9438b25538 | ||
|
|
6c15ca2c3b | ||
|
|
39782fa339 | ||
|
|
d7e29e2ee5 | ||
|
|
6b4693eaaf | ||
|
|
7f816b03d5 | ||
|
|
ed3db4427b | ||
|
|
80ca8c3ca3 | ||
|
|
e43473734e | ||
|
|
8a468b8352 | ||
|
|
51ce10cfc7 | ||
|
|
b5f7144c9c | ||
|
|
86a931d383 | ||
|
|
3e890721c5 | ||
|
|
62d1c64a3d | ||
|
|
c025b186cd | ||
|
|
e999c3a969 | ||
|
|
351403e611 | ||
|
|
c773477a43 | ||
|
|
5d1f0ce3b6 | ||
|
|
7e0fd6c21b | ||
|
|
3bf52f5da0 | ||
|
|
bd856d8f9e | ||
|
|
73b2be752e | ||
|
|
dda7a7a34a | ||
|
|
f238e05533 | ||
|
|
aaaebd0c05 | ||
|
|
9a1924422e | ||
|
|
e446c618ce | ||
|
|
60d35acff9 | ||
|
|
c9adab53a9 | ||
|
|
72b6b2027b | ||
|
|
60239bad82 | ||
|
|
aecd589308 | ||
|
|
ee45cee8e3 | ||
|
|
21e5dfb338 | ||
|
|
b73a4cd666 | ||
|
|
05418fdda1 | ||
|
|
a717fd7c68 | ||
|
|
8408d7350e | ||
|
|
3ba8f56db2 | ||
|
|
7a0946e3b7 | ||
|
|
50c9369d71 | ||
|
|
6c2a34f507 | ||
|
|
ee2c105040 | ||
|
|
3ac83912f3 | ||
|
|
e62fcf7765 |
14
pom.xml
14
pom.xml
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
<groupId>com.bwssystems.HABridge</groupId>
|
<groupId>com.bwssystems.HABridge</groupId>
|
||||||
<artifactId>ha-bridge</artifactId>
|
<artifactId>ha-bridge</artifactId>
|
||||||
<version>1.4.2</version>
|
<version>3.1.0</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>HA Bridge</name>
|
<name>HA Bridge</name>
|
||||||
@@ -89,18 +89,8 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.code.gson</groupId>
|
<groupId>com.google.code.gson</groupId>
|
||||||
<artifactId>gson</artifactId>
|
<artifactId>gson</artifactId>
|
||||||
<version>2.2.4</version>
|
<version>2.6.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>com.fasterxml.jackson.core</groupId>
|
|
||||||
<artifactId>jackson-databind</artifactId>
|
|
||||||
<version>2.6.0</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.cedarsoftware</groupId>
|
|
||||||
<artifactId>json-io</artifactId>
|
|
||||||
<version>4.1.6</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.java.dev.eval</groupId>
|
<groupId>net.java.dev.eval</groupId>
|
||||||
<artifactId>eval</artifactId>
|
<artifactId>eval</artifactId>
|
||||||
|
|||||||
@@ -9,7 +9,10 @@ import java.nio.file.Files;
|
|||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.nio.file.StandardOpenOption;
|
import java.nio.file.StandardOpenOption;
|
||||||
|
import java.nio.file.attribute.PosixFilePermission;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.apache.http.conn.util.InetAddressUtils;
|
import org.apache.http.conn.util.InetAddressUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -20,6 +23,7 @@ import com.bwssystems.util.JsonTransformer;
|
|||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
public class BridgeSettings extends BackupHandler {
|
public class BridgeSettings extends BackupHandler {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(BridgeSettings.class);
|
||||||
private BridgeSettingsDescriptor theBridgeSettings;
|
private BridgeSettingsDescriptor theBridgeSettings;
|
||||||
private BridgeControlDescriptor bridgeControl;
|
private BridgeControlDescriptor bridgeControl;
|
||||||
|
|
||||||
@@ -35,7 +39,6 @@ public class BridgeSettings extends BackupHandler {
|
|||||||
return theBridgeSettings;
|
return theBridgeSettings;
|
||||||
}
|
}
|
||||||
public void buildSettings() {
|
public void buildSettings() {
|
||||||
Logger log = LoggerFactory.getLogger(BridgeSettings.class);
|
|
||||||
InetAddress address = null;
|
InetAddress address = null;
|
||||||
String addressString = null;
|
String addressString = null;
|
||||||
String theVeraAddress = null;
|
String theVeraAddress = null;
|
||||||
@@ -47,7 +50,7 @@ public class BridgeSettings extends BackupHandler {
|
|||||||
if(Files.exists(filePath) && Files.isReadable(filePath))
|
if(Files.exists(filePath) && Files.isReadable(filePath))
|
||||||
configFileProperty = Configuration.CONFIG_FILE;
|
configFileProperty = Configuration.CONFIG_FILE;
|
||||||
}
|
}
|
||||||
|
String serverPortOverride = System.getProperty("server.port");
|
||||||
if(configFileProperty != null)
|
if(configFileProperty != null)
|
||||||
{
|
{
|
||||||
log.info("reading from config file: " + configFileProperty);
|
log.info("reading from config file: " + configFileProperty);
|
||||||
@@ -146,14 +149,24 @@ public class BridgeSettings extends BackupHandler {
|
|||||||
theBridgeSettings.setUpnpDeviceDb(Configuration.DEVICE_DB_DIRECTORY);
|
theBridgeSettings.setUpnpDeviceDb(Configuration.DEVICE_DB_DIRECTORY);
|
||||||
|
|
||||||
if(theBridgeSettings.getNumberoflogmessages() == null)
|
if(theBridgeSettings.getNumberoflogmessages() == null)
|
||||||
theBridgeSettings.setNumberoflogmessages(Configuration.NUMBER_OF_LOG_MESSAGES);
|
theBridgeSettings.setNumberoflogmessages(new Integer(Configuration.NUMBER_OF_LOG_MESSAGES));
|
||||||
|
|
||||||
|
if(theBridgeSettings.getNumberoflogmessages() <= 0)
|
||||||
|
theBridgeSettings.setNumberoflogmessages(new Integer(Configuration.NUMBER_OF_LOG_MESSAGES));
|
||||||
|
|
||||||
|
if(theBridgeSettings.getButtonsleep() == null)
|
||||||
|
theBridgeSettings.setButtonsleep(Integer.parseInt(Configuration.DEFAULT_BUTTON_SLEEP));
|
||||||
|
|
||||||
if(theBridgeSettings.getButtonsleep() <= 0)
|
if(theBridgeSettings.getButtonsleep() < 0)
|
||||||
theBridgeSettings.setButtonsleep(Integer.parseInt(Configuration.DEFAULT_BUTTON_SLEEP));
|
theBridgeSettings.setButtonsleep(Integer.parseInt(Configuration.DEFAULT_BUTTON_SLEEP));
|
||||||
|
|
||||||
theBridgeSettings.setVeraconfigured(theBridgeSettings.isValidVera());
|
theBridgeSettings.setVeraconfigured(theBridgeSettings.isValidVera());
|
||||||
theBridgeSettings.setHarmonyconfigured(theBridgeSettings.isValidHarmony());
|
theBridgeSettings.setHarmonyconfigured(theBridgeSettings.isValidHarmony());
|
||||||
theBridgeSettings.setNestConfigured(theBridgeSettings.isValidNest());
|
theBridgeSettings.setNestConfigured(theBridgeSettings.isValidNest());
|
||||||
|
theBridgeSettings.setHueconfigured(theBridgeSettings.isValidHue());
|
||||||
|
theBridgeSettings.setHalconfigured(theBridgeSettings.isValidHal());
|
||||||
|
if(serverPortOverride != null)
|
||||||
|
theBridgeSettings.setServerPort(serverPortOverride);
|
||||||
setupParams(Paths.get(theBridgeSettings.getConfigfile()), ".cfgbk", "habridge.config-");
|
setupParams(Paths.get(theBridgeSettings.getConfigfile()), ".cfgbk", "habridge.config-");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,29 +181,18 @@ public class BridgeSettings extends BackupHandler {
|
|||||||
|
|
||||||
private void _loadConfig(Path aPath) {
|
private void _loadConfig(Path aPath) {
|
||||||
String jsonContent = configReader(aPath);
|
String jsonContent = configReader(aPath);
|
||||||
BridgeSettingsDescriptor aBridgeSettings = new Gson().fromJson(jsonContent, BridgeSettingsDescriptor.class);
|
if(jsonContent == null)
|
||||||
theBridgeSettings.setButtonsleep(aBridgeSettings.getButtonsleep());
|
return;
|
||||||
theBridgeSettings.setUpnpConfigAddress(aBridgeSettings.getUpnpConfigAddress());
|
try {
|
||||||
theBridgeSettings.setServerPort(aBridgeSettings.getServerPort());
|
theBridgeSettings = new Gson().fromJson(jsonContent, BridgeSettingsDescriptor.class);
|
||||||
theBridgeSettings.setUpnpResponsePort(aBridgeSettings.getUpnpResponsePort());
|
} catch (Exception e) {
|
||||||
theBridgeSettings.setUpnpDeviceDb(aBridgeSettings.getUpnpDeviceDb());
|
log.warn("Issue loading values from file: " + aPath.toUri().toString() + ", Gson convert failed.");
|
||||||
theBridgeSettings.setVeraAddress(aBridgeSettings.getVeraAddress());
|
theBridgeSettings = new BridgeSettingsDescriptor();
|
||||||
theBridgeSettings.setHarmonyAddress(aBridgeSettings.getHarmonyAddress());
|
theBridgeSettings.setConfigfile(aPath.toString());
|
||||||
theBridgeSettings.setHarmonyUser(aBridgeSettings.getHarmonyUser());
|
}
|
||||||
theBridgeSettings.setHarmonyPwd(aBridgeSettings.getHarmonyPwd());
|
|
||||||
theBridgeSettings.setUpnpStrict(aBridgeSettings.isUpnpStrict());
|
|
||||||
theBridgeSettings.setTraceupnp(aBridgeSettings.isTraceupnp());
|
|
||||||
theBridgeSettings.setNestuser(aBridgeSettings.getNestuser());
|
|
||||||
theBridgeSettings.setNestpwd(aBridgeSettings.getNestpwd());
|
|
||||||
theBridgeSettings.setVeraconfigured(aBridgeSettings.isValidVera());
|
|
||||||
theBridgeSettings.setHarmonyconfigured(aBridgeSettings.isValidHarmony());
|
|
||||||
theBridgeSettings.setNestConfigured(aBridgeSettings.isValidNest());
|
|
||||||
theBridgeSettings.setNumberoflogmessages(aBridgeSettings.getNumberoflogmessages());
|
|
||||||
theBridgeSettings.setFarenheit(aBridgeSettings.isFarenheit());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void save(BridgeSettingsDescriptor newBridgeSettings) {
|
public void save(BridgeSettingsDescriptor newBridgeSettings) {
|
||||||
Logger log = LoggerFactory.getLogger(BridgeSettings.class);
|
|
||||||
log.debug("Save HA Bridge settings.");
|
log.debug("Save HA Bridge settings.");
|
||||||
Path configPath = Paths.get(theBridgeSettings.getConfigfile());
|
Path configPath = Paths.get(theBridgeSettings.getConfigfile());
|
||||||
JsonTransformer aRenderer = new JsonTransformer();
|
JsonTransformer aRenderer = new JsonTransformer();
|
||||||
@@ -201,7 +203,6 @@ public class BridgeSettings extends BackupHandler {
|
|||||||
|
|
||||||
|
|
||||||
private void configWriter(String content, Path filePath) {
|
private void configWriter(String content, Path filePath) {
|
||||||
Logger log = LoggerFactory.getLogger(BridgeSettings.class);
|
|
||||||
if(Files.exists(filePath) && !Files.isWritable(filePath)){
|
if(Files.exists(filePath) && !Files.isWritable(filePath)){
|
||||||
log.error("Error file is not writable: " + filePath);
|
log.error("Error file is not writable: " + filePath);
|
||||||
return;
|
return;
|
||||||
@@ -222,6 +223,19 @@ public class BridgeSettings extends BackupHandler {
|
|||||||
Files.move(filePath, target);
|
Files.move(filePath, target);
|
||||||
}
|
}
|
||||||
Files.write(filePath, content.getBytes(), StandardOpenOption.CREATE);
|
Files.write(filePath, content.getBytes(), StandardOpenOption.CREATE);
|
||||||
|
|
||||||
|
// set attributes to be for user only
|
||||||
|
// using PosixFilePermission to set file permissions
|
||||||
|
Set<PosixFilePermission> perms = new HashSet<PosixFilePermission>();
|
||||||
|
// add owners permission
|
||||||
|
perms.add(PosixFilePermission.OWNER_READ);
|
||||||
|
perms.add(PosixFilePermission.OWNER_WRITE);
|
||||||
|
|
||||||
|
try {
|
||||||
|
Files.setPosixFilePermissions(filePath, perms);
|
||||||
|
} catch(UnsupportedOperationException e) {
|
||||||
|
log.info("Cannot set permissions for config file on this system as it is not supported. Continuing");
|
||||||
|
}
|
||||||
if(target != null)
|
if(target != null)
|
||||||
Files.delete(target);
|
Files.delete(target);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@@ -230,15 +244,12 @@ public class BridgeSettings extends BackupHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String configReader(Path filePath) {
|
private String configReader(Path filePath) {
|
||||||
Logger log = LoggerFactory.getLogger(BridgeSettings.class);
|
|
||||||
|
|
||||||
String content = null;
|
String content = null;
|
||||||
if(Files.notExists(filePath) || !Files.isReadable(filePath)){
|
if(Files.notExists(filePath) || !Files.isReadable(filePath)){
|
||||||
log.warn("Error reading the file: " + filePath + " - Does not exist or is not readable. continuing...");
|
log.warn("Error reading the file: " + filePath + " - Does not exist or is not readable. continuing...");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
content = new String(Files.readAllBytes(filePath));
|
content = new String(Files.readAllBytes(filePath));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
package com.bwssystems.HABridge;
|
package com.bwssystems.HABridge;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.bwssystems.HABridge.api.hue.WhitelistEntry;
|
||||||
|
|
||||||
public class BridgeSettingsDescriptor {
|
public class BridgeSettingsDescriptor {
|
||||||
private String upnpconfigaddress;
|
private String upnpconfigaddress;
|
||||||
@@ -22,6 +25,13 @@ public class BridgeSettingsDescriptor {
|
|||||||
private boolean farenheit;
|
private boolean farenheit;
|
||||||
private String configfile;
|
private String configfile;
|
||||||
private Integer numberoflogmessages;
|
private Integer numberoflogmessages;
|
||||||
|
private IpList hueaddress;
|
||||||
|
private boolean hueconfigured;
|
||||||
|
private IpList haladdress;
|
||||||
|
private String haltoken;
|
||||||
|
private boolean halconfigured;
|
||||||
|
private Map<String, WhitelistEntry> whitelist;
|
||||||
|
private boolean settingsChanged;
|
||||||
|
|
||||||
public BridgeSettingsDescriptor() {
|
public BridgeSettingsDescriptor() {
|
||||||
super();
|
super();
|
||||||
@@ -30,7 +40,11 @@ public class BridgeSettingsDescriptor {
|
|||||||
this.nestconfigured = false;
|
this.nestconfigured = false;
|
||||||
this.veraconfigured = false;
|
this.veraconfigured = false;
|
||||||
this.harmonyconfigured = false;
|
this.harmonyconfigured = false;
|
||||||
|
this.hueconfigured = false;
|
||||||
|
this.halconfigured = false;
|
||||||
this.farenheit = true;
|
this.farenheit = true;
|
||||||
|
this.whitelist = null;
|
||||||
|
this.settingsChanged = false;
|
||||||
}
|
}
|
||||||
public String getUpnpConfigAddress() {
|
public String getUpnpConfigAddress() {
|
||||||
return upnpconfigaddress;
|
return upnpconfigaddress;
|
||||||
@@ -152,6 +166,48 @@ public class BridgeSettingsDescriptor {
|
|||||||
public void setFarenheit(boolean farenheit) {
|
public void setFarenheit(boolean farenheit) {
|
||||||
this.farenheit = farenheit;
|
this.farenheit = farenheit;
|
||||||
}
|
}
|
||||||
|
public IpList getHueaddress() {
|
||||||
|
return hueaddress;
|
||||||
|
}
|
||||||
|
public void setHueaddress(IpList hueaddress) {
|
||||||
|
this.hueaddress = hueaddress;
|
||||||
|
}
|
||||||
|
public boolean isHueconfigured() {
|
||||||
|
return hueconfigured;
|
||||||
|
}
|
||||||
|
public void setHueconfigured(boolean hueconfigured) {
|
||||||
|
this.hueconfigured = hueconfigured;
|
||||||
|
}
|
||||||
|
public IpList getHaladdress() {
|
||||||
|
return haladdress;
|
||||||
|
}
|
||||||
|
public void setHaladdress(IpList haladdress) {
|
||||||
|
this.haladdress = haladdress;
|
||||||
|
}
|
||||||
|
public String getHaltoken() {
|
||||||
|
return haltoken;
|
||||||
|
}
|
||||||
|
public void setHaltoken(String haltoken) {
|
||||||
|
this.haltoken = haltoken;
|
||||||
|
}
|
||||||
|
public boolean isHalconfigured() {
|
||||||
|
return halconfigured;
|
||||||
|
}
|
||||||
|
public void setHalconfigured(boolean halconfigured) {
|
||||||
|
this.halconfigured = halconfigured;
|
||||||
|
}
|
||||||
|
public Map<String, WhitelistEntry> getWhitelist() {
|
||||||
|
return whitelist;
|
||||||
|
}
|
||||||
|
public void setWhitelist(Map<String, WhitelistEntry> whitelist) {
|
||||||
|
this.whitelist = whitelist;
|
||||||
|
}
|
||||||
|
public boolean isSettingsChanged() {
|
||||||
|
return settingsChanged;
|
||||||
|
}
|
||||||
|
public void setSettingsChanged(boolean settingsChanged) {
|
||||||
|
this.settingsChanged = settingsChanged;
|
||||||
|
}
|
||||||
public Boolean isValidVera() {
|
public Boolean isValidVera() {
|
||||||
if(this.getVeraAddress() == null || this.getVeraAddress().getDevices().size() <= 0)
|
if(this.getVeraAddress() == null || this.getVeraAddress().getDevices().size() <= 0)
|
||||||
return false;
|
return false;
|
||||||
@@ -179,5 +235,22 @@ public class BridgeSettingsDescriptor {
|
|||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
public Boolean isValidHue() {
|
||||||
|
if(this.getHueaddress() == null || this.getHueaddress().getDevices().size() <= 0)
|
||||||
|
return false;
|
||||||
|
List<NamedIP> devicesList = this.getHueaddress().getDevices();
|
||||||
|
if(devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
public Boolean isValidHal() {
|
||||||
|
if(this.getHaladdress() == null || this.getHaladdress().getDevices().size() <= 0)
|
||||||
|
return false;
|
||||||
|
List<NamedIP> devicesList = this.getHaladdress().getDevices();
|
||||||
|
if(devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS))
|
||||||
|
return false;
|
||||||
|
if(this.getHaltoken() == null || this.getHaltoken().equals(""))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,9 @@ import com.bwssystems.HABridge.hue.HueMulator;
|
|||||||
import com.bwssystems.HABridge.upnp.UpnpListener;
|
import com.bwssystems.HABridge.upnp.UpnpListener;
|
||||||
import com.bwssystems.HABridge.upnp.UpnpSettingsResource;
|
import com.bwssystems.HABridge.upnp.UpnpSettingsResource;
|
||||||
import com.bwssystems.NestBridge.NestHome;
|
import com.bwssystems.NestBridge.NestHome;
|
||||||
|
import com.bwssystems.hal.HalHome;
|
||||||
import com.bwssystems.harmony.HarmonyHome;
|
import com.bwssystems.harmony.HarmonyHome;
|
||||||
|
import com.bwssystems.hue.HueHome;
|
||||||
|
|
||||||
public class HABridge {
|
public class HABridge {
|
||||||
|
|
||||||
@@ -34,6 +36,8 @@ public class HABridge {
|
|||||||
DeviceResource theResources;
|
DeviceResource theResources;
|
||||||
HarmonyHome harmonyHome;
|
HarmonyHome harmonyHome;
|
||||||
NestHome nestHome;
|
NestHome nestHome;
|
||||||
|
HueHome hueHome;
|
||||||
|
HalHome halHome;
|
||||||
HueMulator theHueMulator;
|
HueMulator theHueMulator;
|
||||||
UpnpSettingsResource theSettingResponder;
|
UpnpSettingsResource theSettingResponder;
|
||||||
UpnpListener theUpnpListener;
|
UpnpListener theUpnpListener;
|
||||||
@@ -62,10 +66,14 @@ public class HABridge {
|
|||||||
harmonyHome = new HarmonyHome(bridgeSettings.getBridgeSettingsDescriptor());
|
harmonyHome = new HarmonyHome(bridgeSettings.getBridgeSettingsDescriptor());
|
||||||
//setup the nest connection if available
|
//setup the nest connection if available
|
||||||
nestHome = new NestHome(bridgeSettings.getBridgeSettingsDescriptor());
|
nestHome = new NestHome(bridgeSettings.getBridgeSettingsDescriptor());
|
||||||
|
//setup the hue passtrhu configuration if available
|
||||||
|
hueHome = new HueHome(bridgeSettings.getBridgeSettingsDescriptor());
|
||||||
|
//setup the hal configuration if available
|
||||||
|
halHome = new HalHome(bridgeSettings.getBridgeSettingsDescriptor());
|
||||||
// setup the class to handle the resource setup rest api
|
// setup the class to handle the resource setup rest api
|
||||||
theResources = new DeviceResource(bridgeSettings.getBridgeSettingsDescriptor(), harmonyHome, nestHome);
|
theResources = new DeviceResource(bridgeSettings.getBridgeSettingsDescriptor(), harmonyHome, nestHome, hueHome, halHome);
|
||||||
// setup the class to handle the hue emulator rest api
|
// setup the class to handle the hue emulator rest api
|
||||||
theHueMulator = new HueMulator(bridgeSettings.getBridgeSettingsDescriptor(), theResources.getDeviceRepository(), harmonyHome, nestHome);
|
theHueMulator = new HueMulator(bridgeSettings.getBridgeSettingsDescriptor(), theResources.getDeviceRepository(), harmonyHome, nestHome, hueHome);
|
||||||
theHueMulator.setupServer();
|
theHueMulator.setupServer();
|
||||||
// setup the class to handle the upnp response rest api
|
// setup the class to handle the upnp response rest api
|
||||||
theSettingResponder = new UpnpSettingsResource(bridgeSettings.getBridgeSettingsDescriptor());
|
theSettingResponder = new UpnpSettingsResource(bridgeSettings.getBridgeSettingsDescriptor());
|
||||||
@@ -77,7 +85,10 @@ public class HABridge {
|
|||||||
theUpnpListener = new UpnpListener(bridgeSettings.getBridgeSettingsDescriptor(), bridgeSettings.getBridgeControl());
|
theUpnpListener = new UpnpListener(bridgeSettings.getBridgeSettingsDescriptor(), bridgeSettings.getBridgeControl());
|
||||||
if(theUpnpListener.startListening())
|
if(theUpnpListener.startListening())
|
||||||
log.info("HA Bridge (v" + theVersion.getVersion() + ") reinitialization requessted....");
|
log.info("HA Bridge (v" + theVersion.getVersion() + ") reinitialization requessted....");
|
||||||
|
else
|
||||||
|
bridgeSettings.getBridgeControl().setStop(true);
|
||||||
|
if(bridgeSettings.getBridgeSettingsDescriptor().isSettingsChanged())
|
||||||
|
bridgeSettings.save(bridgeSettings.getBridgeSettingsDescriptor());
|
||||||
bridgeSettings.getBridgeControl().setReinit(false);
|
bridgeSettings.getBridgeControl().setReinit(false);
|
||||||
stop();
|
stop();
|
||||||
nestHome.closeTheNest();
|
nestHome.closeTheNest();
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import com.bwssystems.HABridge.dao.BackupFilename;
|
|||||||
import com.bwssystems.logservices.LoggerInfo;
|
import com.bwssystems.logservices.LoggerInfo;
|
||||||
import com.bwssystems.logservices.LoggingForm;
|
import com.bwssystems.logservices.LoggingForm;
|
||||||
import com.bwssystems.logservices.LoggingManager;
|
import com.bwssystems.logservices.LoggingManager;
|
||||||
import com.bwssystems.util.JsonFreeTextStringFormatter;
|
import com.bwssystems.util.TextStringFormatter;
|
||||||
import com.bwssystems.util.JsonTransformer;
|
import com.bwssystems.util.JsonTransformer;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ public class SystemControl {
|
|||||||
LoggingEvent le;
|
LoggingEvent le;
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
le = (LoggingEvent) cyclicBufferAppender.get(i);
|
le = (LoggingEvent) cyclicBufferAppender.get(i);
|
||||||
logMsgs = logMsgs + ( i > 0?",{":"{") + "\"time\":\"" + dateFormat.format(le.getTimeStamp()) + "\",\"level\":\"" + le.getLevel().levelStr + "\",\"component\":\"" + le.getLoggerName() + "\",\"message\":\"" + JsonFreeTextStringFormatter.forJSON(le.getFormattedMessage()) + "\"}";
|
logMsgs = logMsgs + ( i > 0?",{":"{") + "\"time\":\"" + dateFormat.format(le.getTimeStamp()) + "\",\"level\":\"" + le.getLevel().levelStr + "\",\"component\":\"" + le.getLoggerName() + "\",\"message\":\"" + TextStringFormatter.forJSON(le.getFormattedMessage()) + "\"}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logMsgs = logMsgs + "]";
|
logMsgs = logMsgs + "]";
|
||||||
|
|||||||
13
src/main/java/com/bwssystems/HABridge/api/CallItem.java
Normal file
13
src/main/java/com/bwssystems/HABridge/api/CallItem.java
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package com.bwssystems.HABridge.api;
|
||||||
|
|
||||||
|
public class CallItem {
|
||||||
|
private String item;
|
||||||
|
|
||||||
|
public String getItem() {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setItem(String anitem) {
|
||||||
|
item = anitem;
|
||||||
|
}
|
||||||
|
}
|
||||||
18
src/main/java/com/bwssystems/HABridge/api/NameValue.java
Normal file
18
src/main/java/com/bwssystems/HABridge/api/NameValue.java
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package com.bwssystems.HABridge.api;
|
||||||
|
|
||||||
|
public class NameValue {
|
||||||
|
private String name;
|
||||||
|
private String value;
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
public void setValue(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.bwssystems.HABridge.api;
|
||||||
|
|
||||||
|
public class SuccessUserResponse {
|
||||||
|
private UserCreateResponse success;
|
||||||
|
|
||||||
|
public UserCreateResponse getSuccess() {
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSuccess(UserCreateResponse success) {
|
||||||
|
this.success = success;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.bwssystems.HABridge.api;
|
||||||
|
|
||||||
|
public class UserCreateResponse {
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsername(String username) {
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@ public class DeviceResponse {
|
|||||||
private String name;
|
private String name;
|
||||||
private String modelid;
|
private String modelid;
|
||||||
private String manufacturername;
|
private String manufacturername;
|
||||||
|
private String luminaireuniqueid;
|
||||||
private String uniqueid;
|
private String uniqueid;
|
||||||
private String swversion;
|
private String swversion;
|
||||||
|
|
||||||
@@ -70,15 +71,17 @@ public class DeviceResponse {
|
|||||||
this.swversion = swversion;
|
this.swversion = swversion;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DeviceResponse createResponse(DeviceDescriptor device){
|
public String getLuminaireuniqueid() {
|
||||||
DeviceState deviceState = new DeviceState();
|
return luminaireuniqueid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLuminaireuniqueid(String luminaireuniqueid) {
|
||||||
|
this.luminaireuniqueid = luminaireuniqueid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DeviceResponse createResponse(DeviceDescriptor device){
|
||||||
DeviceResponse response = new DeviceResponse();
|
DeviceResponse response = new DeviceResponse();
|
||||||
response.setState(deviceState);
|
response.setState(device.getDeviceState());
|
||||||
deviceState.setOn(device.getDeviceState());
|
|
||||||
deviceState.setReachable(true);
|
|
||||||
deviceState.setEffect("none");
|
|
||||||
deviceState.setAlert("none");
|
|
||||||
deviceState.setBri(device.getDeviceSetValue());
|
|
||||||
|
|
||||||
response.setName(device.getName());
|
response.setName(device.getName());
|
||||||
response.setUniqueid(device.getId());
|
response.setUniqueid(device.getId());
|
||||||
@@ -86,6 +89,7 @@ public class DeviceResponse {
|
|||||||
response.setType("Dimmable light");
|
response.setType("Dimmable light");
|
||||||
response.setModelid("LWB004");
|
response.setModelid("LWB004");
|
||||||
response.setSwversion("66012040");
|
response.setSwversion("66012040");
|
||||||
|
response.setLuminaireuniqueid(null);
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,23 @@
|
|||||||
package com.bwssystems.HABridge.api.hue;
|
package com.bwssystems.HABridge.api.hue;
|
||||||
|
|
||||||
|
// import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by arm on 4/14/15.
|
* Created by arm on 4/14/15.
|
||||||
*/
|
*/
|
||||||
public class DeviceState {
|
public class DeviceState {
|
||||||
private boolean on;
|
private boolean on;
|
||||||
private int bri = 0;
|
private int bri;
|
||||||
|
private int hue;
|
||||||
|
private int sat;
|
||||||
private String effect;
|
private String effect;
|
||||||
|
private int ct;
|
||||||
private String alert;
|
private String alert;
|
||||||
|
private String colormode;
|
||||||
private boolean reachable;
|
private boolean reachable;
|
||||||
|
private List<Double> xy;
|
||||||
|
private int transitiontime;
|
||||||
|
|
||||||
public boolean isOn() {
|
public boolean isOn() {
|
||||||
return on;
|
return on;
|
||||||
@@ -27,6 +35,22 @@ public class DeviceState {
|
|||||||
this.bri = bri;
|
this.bri = bri;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getHue() {
|
||||||
|
return hue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHue(int hue) {
|
||||||
|
this.hue = hue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSat() {
|
||||||
|
return sat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSat(int sat) {
|
||||||
|
this.sat = sat;
|
||||||
|
}
|
||||||
|
|
||||||
public String getEffect() {
|
public String getEffect() {
|
||||||
return effect;
|
return effect;
|
||||||
}
|
}
|
||||||
@@ -35,6 +59,14 @@ public class DeviceState {
|
|||||||
this.effect = effect;
|
this.effect = effect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getCt() {
|
||||||
|
return ct;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCt(int ct) {
|
||||||
|
this.ct = ct;
|
||||||
|
}
|
||||||
|
|
||||||
public String getAlert() {
|
public String getAlert() {
|
||||||
return alert;
|
return alert;
|
||||||
}
|
}
|
||||||
@@ -43,6 +75,14 @@ public class DeviceState {
|
|||||||
this.alert = alert;
|
this.alert = alert;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getColormode() {
|
||||||
|
return colormode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setColormode(String colormode) {
|
||||||
|
this.colormode = colormode;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isReachable() {
|
public boolean isReachable() {
|
||||||
return reachable;
|
return reachable;
|
||||||
}
|
}
|
||||||
@@ -51,6 +91,39 @@ public class DeviceState {
|
|||||||
this.reachable = reachable;
|
this.reachable = reachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Double> getXy() {
|
||||||
|
return xy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setXy(List<Double> xy) {
|
||||||
|
this.xy = xy;
|
||||||
|
}
|
||||||
|
public int getTransitiontime() {
|
||||||
|
return transitiontime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransitiontime(int transitiontime) {
|
||||||
|
this.transitiontime = transitiontime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DeviceState createDeviceState() {
|
||||||
|
DeviceState newDeviceState = new DeviceState();
|
||||||
|
newDeviceState.fillIn();
|
||||||
|
// newDeviceState.setColormode("none");
|
||||||
|
// ArrayList<Double> doubleArray = new ArrayList<Double>();
|
||||||
|
// doubleArray.add(new Double(0));
|
||||||
|
// doubleArray.add(new Double(0));
|
||||||
|
// newDeviceState.setXy(doubleArray);
|
||||||
|
|
||||||
|
return newDeviceState;
|
||||||
|
}
|
||||||
|
public void fillIn() {
|
||||||
|
if(this.getAlert() == null)
|
||||||
|
this.setAlert("none");
|
||||||
|
if(this.getEffect() == null)
|
||||||
|
this.setEffect("none");
|
||||||
|
this.setReachable(true);
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "DeviceState{" +
|
return "DeviceState{" +
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.bwssystems.HABridge.api.hue;
|
||||||
|
|
||||||
|
public class DeviceTypes {
|
||||||
|
private Boolean bridge;
|
||||||
|
private String[] lights;
|
||||||
|
public Boolean getBridge() {
|
||||||
|
return bridge;
|
||||||
|
}
|
||||||
|
public void setBridge(Boolean bridge) {
|
||||||
|
this.bridge = bridge;
|
||||||
|
}
|
||||||
|
public String[] getLights() {
|
||||||
|
return lights;
|
||||||
|
}
|
||||||
|
public void setLights(String[] lights) {
|
||||||
|
this.lights = lights;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package com.bwssystems.HABridge.api.hue;
|
||||||
|
|
||||||
|
public class GroupResponse {
|
||||||
|
private DeviceState action;
|
||||||
|
private String[] lights;
|
||||||
|
private String name;
|
||||||
|
public DeviceState getAction() {
|
||||||
|
return action;
|
||||||
|
}
|
||||||
|
public void setAction(DeviceState action) {
|
||||||
|
this.action = action;
|
||||||
|
}
|
||||||
|
public String[] getLights() {
|
||||||
|
return lights;
|
||||||
|
}
|
||||||
|
public void setLights(String[] lights) {
|
||||||
|
this.lights = lights;
|
||||||
|
}
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GroupResponse createGroupResponse(String[] theLights) {
|
||||||
|
GroupResponse theResponse = new GroupResponse();
|
||||||
|
theResponse.setAction(DeviceState.createDeviceState());
|
||||||
|
theResponse.setName("Lightset 0");
|
||||||
|
theResponse.setLights(theLights);
|
||||||
|
return theResponse;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,22 +4,23 @@ import java.util.HashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.bwssystems.HABridge.api.hue.DeviceResponse;
|
import com.bwssystems.HABridge.api.hue.DeviceResponse;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by arm on 4/14/15.
|
* Created by arm on 4/14/15.
|
||||||
*/
|
*/
|
||||||
public class HueApiResponse {
|
public class HueApiResponse {
|
||||||
private Map<String, DeviceResponse> lights;
|
private Map<String, DeviceResponse> lights;
|
||||||
private Map<String, String> scenes;
|
private Map<String, JsonObject> scenes;
|
||||||
private Map<String, String> groups;
|
private Map<String, JsonObject> groups;
|
||||||
private Map<String, String> schedules;
|
private Map<String, JsonObject> schedules;
|
||||||
private Map<String, String> sensors;
|
private Map<String, JsonObject> sensors;
|
||||||
private Map<String, String> rules;
|
private Map<String, JsonObject> rules;
|
||||||
private HueConfig config;
|
private HueConfig config;
|
||||||
|
|
||||||
public HueApiResponse(String name, String ipaddress, String devicetype, String userid) {
|
public HueApiResponse(String name, String ipaddress, Map<String, WhitelistEntry> awhitelist) {
|
||||||
super();
|
super();
|
||||||
this.setConfig(HueConfig.createConfig(name, ipaddress, devicetype, userid));
|
this.setConfig(HueConfig.createConfig(name, ipaddress, awhitelist));
|
||||||
this.setRules(new HashMap<>());
|
this.setRules(new HashMap<>());
|
||||||
this.setSensors(new HashMap<>());
|
this.setSensors(new HashMap<>());
|
||||||
this.setSchedules(new HashMap<>());
|
this.setSchedules(new HashMap<>());
|
||||||
@@ -35,43 +36,43 @@ public class HueApiResponse {
|
|||||||
this.lights = lights;
|
this.lights = lights;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, String> getScenes() {
|
public Map<String, JsonObject> getScenes() {
|
||||||
return scenes;
|
return scenes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setScenes(Map<String, String> scenes) {
|
public void setScenes(Map<String, JsonObject> scenes) {
|
||||||
this.scenes = scenes;
|
this.scenes = scenes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, String> getGroups() {
|
public Map<String, JsonObject> getGroups() {
|
||||||
return groups;
|
return groups;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setGroups(Map<String, String> groups) {
|
public void setGroups(Map<String, JsonObject> groups) {
|
||||||
this.groups = groups;
|
this.groups = groups;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, String> getSchedules() {
|
public Map<String, JsonObject> getSchedules() {
|
||||||
return schedules;
|
return schedules;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSchedules(Map<String, String> schedules) {
|
public void setSchedules(Map<String, JsonObject> schedules) {
|
||||||
this.schedules = schedules;
|
this.schedules = schedules;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, String> getSensors() {
|
public Map<String, JsonObject> getSensors() {
|
||||||
return sensors;
|
return sensors;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSensors(Map<String, String> sensors) {
|
public void setSensors(Map<String, JsonObject> sensors) {
|
||||||
this.sensors = sensors;
|
this.sensors = sensors;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, String> getRules() {
|
public Map<String, JsonObject> getRules() {
|
||||||
return rules;
|
return rules;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRules(Map<String, String> rules) {
|
public void setRules(Map<String, JsonObject> rules) {
|
||||||
this.rules = rules;
|
this.rules = rules;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import java.net.SocketException;
|
|||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
@@ -29,18 +28,22 @@ public class HueConfig
|
|||||||
private String localtime;
|
private String localtime;
|
||||||
private String timezone;
|
private String timezone;
|
||||||
private String zigbeechannel;
|
private String zigbeechannel;
|
||||||
|
private String modelid;
|
||||||
|
private String bridgeid;
|
||||||
|
private Boolean factorynew;
|
||||||
|
private String replacesbridgeid;
|
||||||
private Map<String, WhitelistEntry> whitelist;
|
private Map<String, WhitelistEntry> whitelist;
|
||||||
|
|
||||||
public static HueConfig createConfig(String name, String ipaddress, String devicetype, String userid) {
|
public static HueConfig createConfig(String name, String ipaddress, Map<String, WhitelistEntry> awhitelist) {
|
||||||
HueConfig aConfig = new HueConfig();
|
HueConfig aConfig = new HueConfig();
|
||||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
|
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
|
||||||
SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
|
SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
|
||||||
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("UTC"));
|
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||||
aConfig.setMac(HueConfig.getMacAddress(ipaddress));
|
aConfig.setMac(HueConfig.getMacAddress(ipaddress));
|
||||||
aConfig.setApiversion("1.4.0");
|
aConfig.setApiversion("1.10.0");
|
||||||
aConfig.setPortalservices(false);
|
aConfig.setPortalservices(false);
|
||||||
aConfig.setGateway(ipaddress);
|
aConfig.setGateway(ipaddress);
|
||||||
aConfig.setSwversion("01005215");
|
aConfig.setSwversion("01028090");
|
||||||
aConfig.setLinkbutton(false);
|
aConfig.setLinkbutton(false);
|
||||||
aConfig.setIpaddress(ipaddress);
|
aConfig.setIpaddress(ipaddress);
|
||||||
aConfig.setProxyport(0);
|
aConfig.setProxyport(0);
|
||||||
@@ -53,8 +56,10 @@ public class HueConfig
|
|||||||
aConfig.setLocaltime(dateFormat.format(new Date()));
|
aConfig.setLocaltime(dateFormat.format(new Date()));
|
||||||
aConfig.setTimezone(TimeZone.getDefault().getID());
|
aConfig.setTimezone(TimeZone.getDefault().getID());
|
||||||
aConfig.setZigbeechannel("6");
|
aConfig.setZigbeechannel("6");
|
||||||
Map<String, WhitelistEntry> awhitelist = new HashMap<>();
|
aConfig.setBridgeid(HuePublicConfig.getBridgeIdFromMac(aConfig.getMac(), ipaddress));
|
||||||
awhitelist.put(userid, WhitelistEntry.createEntry(devicetype));
|
aConfig.setModelid("BSB002");
|
||||||
|
aConfig.setFactorynew(false);
|
||||||
|
aConfig.setReplacesbridgeid(null);
|
||||||
aConfig.setWhitelist(awhitelist);
|
aConfig.setWhitelist(awhitelist);
|
||||||
|
|
||||||
return aConfig;
|
return aConfig;
|
||||||
@@ -235,4 +240,36 @@ public class HueConfig
|
|||||||
public void setZigbeechannel(String zigbeechannel) {
|
public void setZigbeechannel(String zigbeechannel) {
|
||||||
this.zigbeechannel = zigbeechannel;
|
this.zigbeechannel = zigbeechannel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getModelid() {
|
||||||
|
return modelid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setModelid(String modelid) {
|
||||||
|
this.modelid = modelid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBridgeid() {
|
||||||
|
return bridgeid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBridgeid(String bridgeid) {
|
||||||
|
this.bridgeid = bridgeid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getFactorynew() {
|
||||||
|
return factorynew;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFactorynew(Boolean factorynew) {
|
||||||
|
this.factorynew = factorynew;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getReplacesbridgeid() {
|
||||||
|
return replacesbridgeid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReplacesbridgeid(String replacesbridgeid) {
|
||||||
|
this.replacesbridgeid = replacesbridgeid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
19
src/main/java/com/bwssystems/HABridge/api/hue/HueError.java
Normal file
19
src/main/java/com/bwssystems/HABridge/api/hue/HueError.java
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package com.bwssystems.HABridge.api.hue;
|
||||||
|
|
||||||
|
public class HueError {
|
||||||
|
|
||||||
|
private HueErrorDetails error;
|
||||||
|
|
||||||
|
public HueError(HueErrorDetails error) {
|
||||||
|
super();
|
||||||
|
this.error = error;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HueErrorDetails getError() {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setError(HueErrorDetails error) {
|
||||||
|
this.error = error;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package com.bwssystems.HABridge.api.hue;
|
||||||
|
|
||||||
|
public class HueErrorDetails {
|
||||||
|
private String type;
|
||||||
|
private String address;
|
||||||
|
private String description;
|
||||||
|
private String method_name;
|
||||||
|
private String resource_name;
|
||||||
|
private String value;
|
||||||
|
public HueErrorDetails(String type, String address, String description, String method_name, String resource_name,
|
||||||
|
String value) {
|
||||||
|
super();
|
||||||
|
this.type = type;
|
||||||
|
this.address = address;
|
||||||
|
this.description = description;
|
||||||
|
this.method_name = method_name;
|
||||||
|
this.resource_name = resource_name;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
public void setType(String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
public String getAddress() {
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
public void setAddress(String address) {
|
||||||
|
this.address = address;
|
||||||
|
}
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
public String getMethod_name() {
|
||||||
|
return method_name;
|
||||||
|
}
|
||||||
|
public void setMethod_name(String method_name) {
|
||||||
|
this.method_name = method_name;
|
||||||
|
}
|
||||||
|
public String getResource_name() {
|
||||||
|
return resource_name;
|
||||||
|
}
|
||||||
|
public void setResource_name(String resource_name) {
|
||||||
|
this.resource_name = resource_name;
|
||||||
|
}
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
public void setValue(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package com.bwssystems.HABridge.api.hue;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class HueErrorResponse {
|
||||||
|
private ArrayList<HueError> theErrors;
|
||||||
|
|
||||||
|
public HueErrorResponse() {
|
||||||
|
super();
|
||||||
|
theErrors = new ArrayList<HueError>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addError(HueError anError) {
|
||||||
|
theErrors.add(anError);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HueError[] getTheErrors() {
|
||||||
|
HueError theList[] = new HueError[theErrors.size()];
|
||||||
|
theList = theErrors.toArray(theList);
|
||||||
|
return theList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTheErrors(ArrayList<HueError> theErrors) {
|
||||||
|
this.theErrors = theErrors;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,154 @@
|
|||||||
|
package com.bwssystems.HABridge.api.hue;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.NetworkInterface;
|
||||||
|
import java.net.SocketException;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
|
import javax.xml.bind.DatatypeConverter;
|
||||||
|
|
||||||
|
public class HuePublicConfig
|
||||||
|
{
|
||||||
|
private String name;
|
||||||
|
private String apiversion;
|
||||||
|
private String swversion;
|
||||||
|
private String mac;
|
||||||
|
private String bridgeid;
|
||||||
|
private String replacesbridgeid;
|
||||||
|
private Boolean factorynew;
|
||||||
|
private String modelid;
|
||||||
|
|
||||||
|
public static HuePublicConfig createConfig(String name, String ipaddress) {
|
||||||
|
HuePublicConfig aConfig = new HuePublicConfig();
|
||||||
|
aConfig.setMac(HuePublicConfig.getMacAddress(ipaddress));
|
||||||
|
aConfig.setApiversion("1.10.0");
|
||||||
|
aConfig.setSwversion("01028090");
|
||||||
|
aConfig.setName(name);
|
||||||
|
aConfig.setBridgeid(HuePublicConfig.getBridgeIdFromMac(aConfig.getMac(), ipaddress));
|
||||||
|
aConfig.setModelid("BSB002");
|
||||||
|
aConfig.setFactorynew(false);
|
||||||
|
aConfig.setReplacesbridgeid(null);
|
||||||
|
|
||||||
|
return aConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getMacAddress(String addr)
|
||||||
|
{
|
||||||
|
InetAddress ip;
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
try {
|
||||||
|
|
||||||
|
ip = InetAddress.getByName(addr);
|
||||||
|
|
||||||
|
NetworkInterface network = NetworkInterface.getByInetAddress(ip);
|
||||||
|
|
||||||
|
byte[] mac = network.getHardwareAddress();
|
||||||
|
|
||||||
|
for (int i = 0; i < mac.length; i++) {
|
||||||
|
sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? ":" : ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (UnknownHostException e) {
|
||||||
|
|
||||||
|
sb.append("00:00:88:00:bb:ee");
|
||||||
|
|
||||||
|
} catch (SocketException e){
|
||||||
|
|
||||||
|
sb.append("00:00:88:00:bb:ee");
|
||||||
|
|
||||||
|
} catch (Exception e){
|
||||||
|
|
||||||
|
sb.append("00:00:88:00:bb:ee");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static String getBridgeIdFromMac(String macAddr, String ipAddr)
|
||||||
|
{
|
||||||
|
StringTokenizer st = new StringTokenizer(macAddr, ":");
|
||||||
|
String bridgeId = "";
|
||||||
|
String port = null;
|
||||||
|
while(st.hasMoreTokens()) {
|
||||||
|
bridgeId = bridgeId + st.nextToken();
|
||||||
|
}
|
||||||
|
if(ipAddr.contains(":")) {
|
||||||
|
port = ipAddr.substring(ipAddr.indexOf(":"));
|
||||||
|
BigInteger bigInt = BigInteger.valueOf(Integer.getInteger(port).intValue());
|
||||||
|
byte[] theBytes = bigInt.toByteArray();
|
||||||
|
bridgeId = bridgeId + DatatypeConverter.printHexBinary(theBytes);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
bridgeId = bridgeId + "0800";
|
||||||
|
return bridgeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMac() {
|
||||||
|
return mac;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMac(String mac) {
|
||||||
|
this.mac = mac;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSwversion() {
|
||||||
|
return swversion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSwversion(String swversion) {
|
||||||
|
this.swversion = swversion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getApiversion() {
|
||||||
|
return apiversion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApiversion(String apiversion) {
|
||||||
|
this.apiversion = apiversion;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getModelid() {
|
||||||
|
return modelid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setModelid(String modelid) {
|
||||||
|
this.modelid = modelid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBridgeid() {
|
||||||
|
return bridgeid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBridgeid(String bridgeid) {
|
||||||
|
this.bridgeid = bridgeid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getFactorynew() {
|
||||||
|
return factorynew;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFactorynew(Boolean factorynew) {
|
||||||
|
this.factorynew = factorynew;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getReplacesbridgeid() {
|
||||||
|
return replacesbridgeid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReplacesbridgeid(String replacesbridgeid) {
|
||||||
|
this.replacesbridgeid = replacesbridgeid;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,136 @@
|
|||||||
|
package com.bwssystems.HABridge.api.hue;
|
||||||
|
|
||||||
|
// import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by arm on 4/14/15.
|
||||||
|
*/
|
||||||
|
public class StateChangeBody {
|
||||||
|
private boolean on;
|
||||||
|
private int bri;
|
||||||
|
private int hue;
|
||||||
|
private int sat;
|
||||||
|
private String effect;
|
||||||
|
private int ct;
|
||||||
|
private String alert;
|
||||||
|
private List<Double> xy;
|
||||||
|
private int transitiontime;
|
||||||
|
private int bri_inc;
|
||||||
|
private int hue_inc;
|
||||||
|
private int sat_inc;
|
||||||
|
private List<Double> xy_inc;
|
||||||
|
private int ct_inc;
|
||||||
|
|
||||||
|
public boolean isOn() {
|
||||||
|
return on;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOn(boolean on) {
|
||||||
|
this.on = on;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBri() {
|
||||||
|
return bri;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBri(int bri) {
|
||||||
|
this.bri = bri;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHue() {
|
||||||
|
return hue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHue(int hue) {
|
||||||
|
this.hue = hue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSat() {
|
||||||
|
return sat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSat(int sat) {
|
||||||
|
this.sat = sat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEffect() {
|
||||||
|
return effect;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEffect(String effect) {
|
||||||
|
this.effect = effect;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCt() {
|
||||||
|
return ct;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCt(int ct) {
|
||||||
|
this.ct = ct;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAlert() {
|
||||||
|
return alert;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAlert(String alert) {
|
||||||
|
this.alert = alert;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Double> getXy() {
|
||||||
|
return xy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setXy(List<Double> xy) {
|
||||||
|
this.xy = xy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTransitiontime() {
|
||||||
|
return transitiontime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransitiontime(int transitiontime) {
|
||||||
|
this.transitiontime = transitiontime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBri_inc() {
|
||||||
|
return bri_inc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBri_inc(int bri_inc) {
|
||||||
|
this.bri_inc = bri_inc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHue_inc() {
|
||||||
|
return hue_inc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHue_inc(int hue_inc) {
|
||||||
|
this.hue_inc = hue_inc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSat_inc() {
|
||||||
|
return sat_inc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSat_inc(int sat_inc) {
|
||||||
|
this.sat_inc = sat_inc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Double> getXy_inc() {
|
||||||
|
return xy_inc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setXy_inc(List<Double> xy_inc) {
|
||||||
|
this.xy_inc = xy_inc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCt_inc() {
|
||||||
|
return ct_inc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCt_inc(int ct_inc) {
|
||||||
|
this.ct_inc = ct_inc;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,20 +3,36 @@ package com.bwssystems.HABridge.api.hue;
|
|||||||
|
|
||||||
public class Swupdate
|
public class Swupdate
|
||||||
{
|
{
|
||||||
|
private Integer updatestate;
|
||||||
|
private Boolean checkforupdate;
|
||||||
|
private DeviceTypes devicetypes;
|
||||||
private String text;
|
private String text;
|
||||||
private Boolean notify;
|
private Boolean notify;
|
||||||
private Integer updatestate;
|
|
||||||
private String url;
|
private String url;
|
||||||
|
|
||||||
public static Swupdate createSwupdate() {
|
public static Swupdate createSwupdate() {
|
||||||
Swupdate aSwupdate = new Swupdate();
|
Swupdate aSwupdate = new Swupdate();
|
||||||
|
aSwupdate.setUpdatestate(0);
|
||||||
|
aSwupdate.setCheckforupdate(false);
|
||||||
|
aSwupdate.setDevicetypes(new DeviceTypes());
|
||||||
aSwupdate.setNotify(false);
|
aSwupdate.setNotify(false);
|
||||||
aSwupdate.setText("");
|
aSwupdate.setText("");
|
||||||
aSwupdate.setUpdatestate(0);
|
|
||||||
aSwupdate.setUrl("");
|
aSwupdate.setUrl("");
|
||||||
return aSwupdate;
|
return aSwupdate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Boolean getCheckforupdate() {
|
||||||
|
return checkforupdate;
|
||||||
|
}
|
||||||
|
public void setCheckforupdate(Boolean checkforupdate) {
|
||||||
|
this.checkforupdate = checkforupdate;
|
||||||
|
}
|
||||||
|
public DeviceTypes getDevicetypes() {
|
||||||
|
return devicetypes;
|
||||||
|
}
|
||||||
|
public void setDevicetypes(DeviceTypes devicetypes) {
|
||||||
|
this.devicetypes = devicetypes;
|
||||||
|
}
|
||||||
public String getText() {
|
public String getText() {
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.bwssystems.HABridge.dao;
|
package com.bwssystems.HABridge.dao;
|
||||||
|
|
||||||
|
import com.bwssystems.HABridge.api.hue.DeviceState;
|
||||||
import com.google.gson.annotations.Expose;
|
import com.google.gson.annotations.Expose;
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
@@ -34,6 +35,9 @@ public class DeviceDescriptor{
|
|||||||
@SerializedName("onUrl")
|
@SerializedName("onUrl")
|
||||||
@Expose
|
@Expose
|
||||||
private String onUrl;
|
private String onUrl;
|
||||||
|
@SerializedName("headers")
|
||||||
|
@Expose
|
||||||
|
private String headers;
|
||||||
@SerializedName("httpVerb")
|
@SerializedName("httpVerb")
|
||||||
@Expose
|
@Expose
|
||||||
private String httpVerb;
|
private String httpVerb;
|
||||||
@@ -47,8 +51,7 @@ public class DeviceDescriptor{
|
|||||||
@Expose
|
@Expose
|
||||||
private String contentBodyOff;
|
private String contentBodyOff;
|
||||||
|
|
||||||
private boolean deviceState;
|
private DeviceState deviceState;
|
||||||
private int deviceSetValue;
|
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
@@ -122,6 +125,14 @@ public class DeviceDescriptor{
|
|||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getHeaders() {
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHeaders(String headers) {
|
||||||
|
this.headers = headers;
|
||||||
|
}
|
||||||
|
|
||||||
public String getHttpVerb() {
|
public String getHttpVerb() {
|
||||||
return httpVerb;
|
return httpVerb;
|
||||||
}
|
}
|
||||||
@@ -154,21 +165,14 @@ public class DeviceDescriptor{
|
|||||||
this.contentBodyOff = contentBodyOff;
|
this.contentBodyOff = contentBodyOff;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getDeviceState() {
|
public DeviceState getDeviceState() {
|
||||||
|
if(deviceState == null)
|
||||||
|
deviceState = DeviceState.createDeviceState();
|
||||||
return deviceState;
|
return deviceState;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDeviceState(boolean deviceState) {
|
public void setDeviceState(DeviceState deviceState) {
|
||||||
this.deviceState = deviceState;
|
this.deviceState = deviceState;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getDeviceSetValue() {
|
|
||||||
return deviceSetValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDeviceSetValue(int deviceSetValue) {
|
|
||||||
this.deviceSetValue = deviceSetValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,9 @@ import com.bwssystems.HABridge.dao.DeviceDescriptor;
|
|||||||
import com.bwssystems.HABridge.dao.DeviceRepository;
|
import com.bwssystems.HABridge.dao.DeviceRepository;
|
||||||
import com.bwssystems.HABridge.dao.ErrorMessage;
|
import com.bwssystems.HABridge.dao.ErrorMessage;
|
||||||
import com.bwssystems.NestBridge.NestHome;
|
import com.bwssystems.NestBridge.NestHome;
|
||||||
|
import com.bwssystems.hal.HalHome;
|
||||||
import com.bwssystems.harmony.HarmonyHome;
|
import com.bwssystems.harmony.HarmonyHome;
|
||||||
|
import com.bwssystems.hue.HueHome;
|
||||||
import com.bwssystems.luupRequests.Device;
|
import com.bwssystems.luupRequests.Device;
|
||||||
import com.bwssystems.luupRequests.Scene;
|
import com.bwssystems.luupRequests.Scene;
|
||||||
import com.bwssystems.util.JsonTransformer;
|
import com.bwssystems.util.JsonTransformer;
|
||||||
@@ -38,9 +40,11 @@ public class DeviceResource {
|
|||||||
private VeraHome veraHome;
|
private VeraHome veraHome;
|
||||||
private HarmonyHome myHarmonyHome;
|
private HarmonyHome myHarmonyHome;
|
||||||
private NestHome nestHome;
|
private NestHome nestHome;
|
||||||
|
private HueHome hueHome;
|
||||||
|
private HalHome halHome;
|
||||||
private static final Set<String> supportedVerbs = new HashSet<>(Arrays.asList("get", "put", "post"));
|
private static final Set<String> supportedVerbs = new HashSet<>(Arrays.asList("get", "put", "post"));
|
||||||
|
|
||||||
public DeviceResource(BridgeSettingsDescriptor theSettings, HarmonyHome theHarmonyHome, NestHome aNestHome) {
|
public DeviceResource(BridgeSettingsDescriptor theSettings, HarmonyHome theHarmonyHome, NestHome aNestHome, HueHome aHueHome, HalHome aHalHome) {
|
||||||
this.deviceRepository = new DeviceRepository(theSettings.getUpnpDeviceDb());
|
this.deviceRepository = new DeviceRepository(theSettings.getUpnpDeviceDb());
|
||||||
|
|
||||||
if(theSettings.isValidVera())
|
if(theSettings.isValidVera())
|
||||||
@@ -57,7 +61,18 @@ public class DeviceResource {
|
|||||||
this.nestHome = aNestHome;
|
this.nestHome = aNestHome;
|
||||||
else
|
else
|
||||||
this.nestHome = null;
|
this.nestHome = null;
|
||||||
setupEndpoints();
|
|
||||||
|
if(theSettings.isValidHue())
|
||||||
|
this.hueHome = aHueHome;
|
||||||
|
else
|
||||||
|
this.hueHome = null;
|
||||||
|
|
||||||
|
if(theSettings.isValidHal())
|
||||||
|
this.halHome = aHalHome;
|
||||||
|
else
|
||||||
|
this.halHome = null;
|
||||||
|
|
||||||
|
setupEndpoints();
|
||||||
}
|
}
|
||||||
|
|
||||||
public DeviceRepository getDeviceRepository() {
|
public DeviceRepository getDeviceRepository() {
|
||||||
@@ -245,6 +260,26 @@ public class DeviceResource {
|
|||||||
return nestHome.getItems();
|
return nestHome.getItems();
|
||||||
}, new JsonTransformer());
|
}, new JsonTransformer());
|
||||||
|
|
||||||
|
get (API_CONTEXT + "/hue/devices", "application/json", (request, response) -> {
|
||||||
|
log.debug("Get hue items");
|
||||||
|
if(hueHome == null) {
|
||||||
|
response.status(HttpStatus.SC_NOT_FOUND);
|
||||||
|
return new ErrorMessage("A Hue is not available.");
|
||||||
|
}
|
||||||
|
response.status(HttpStatus.SC_OK);
|
||||||
|
return hueHome.getDevices();
|
||||||
|
}, new JsonTransformer());
|
||||||
|
|
||||||
|
get (API_CONTEXT + "/hal/devices", "application/json", (request, response) -> {
|
||||||
|
log.debug("Get hal items");
|
||||||
|
if(halHome == null) {
|
||||||
|
response.status(HttpStatus.SC_NOT_FOUND);
|
||||||
|
return new ErrorMessage("A Hal is not available.");
|
||||||
|
}
|
||||||
|
response.status(HttpStatus.SC_OK);
|
||||||
|
return halHome.getDevices();
|
||||||
|
}, new JsonTransformer());
|
||||||
|
|
||||||
get (API_CONTEXT + "/backup/available", "application/json", (request, response) -> {
|
get (API_CONTEXT + "/backup/available", "application/json", (request, response) -> {
|
||||||
log.debug("Get backup filenames");
|
log.debug("Get backup filenames");
|
||||||
response.status(HttpStatus.SC_OK);
|
response.status(HttpStatus.SC_OK);
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -22,6 +22,21 @@ public class UpnpListener {
|
|||||||
private boolean strict;
|
private boolean strict;
|
||||||
private boolean traceupnp;
|
private boolean traceupnp;
|
||||||
private BridgeControlDescriptor bridgeControl;
|
private BridgeControlDescriptor bridgeControl;
|
||||||
|
private boolean discoveryTemplateLatest;
|
||||||
|
private String discoveryTemplate = "HTTP/1.1 200 OK\r\n" +
|
||||||
|
"CACHE-CONTROL: max-age=86400\r\n" +
|
||||||
|
"EXT:\r\n" +
|
||||||
|
"LOCATION: http://%s:%s/description.xml\r\n" +
|
||||||
|
"SERVER: FreeRTOS/6.0.5, UPnP/1.0, IpBridge/1.10.0\r\n" +
|
||||||
|
"ST: urn:schemas-upnp-org:device:basic:1\r\n" +
|
||||||
|
"USN: uuid:Socket-1_0-221438K0100073::urn:schemas-upnp-org:device:basic:1\r\n\r\n";
|
||||||
|
private String discoveryTemplateOld = "HTTP/1.1 200 OK\r\n" +
|
||||||
|
"CACHE-CONTROL: max-age=86400\r\n" +
|
||||||
|
"EXT:\r\n" +
|
||||||
|
"LOCATION: http://%s:%s/description.xml\r\n" +
|
||||||
|
"SERVER: FreeRTOS/6.0.5, UPnP/1.0, IpBridge/0.1\r\n" +
|
||||||
|
"ST: urn:schemas-upnp-org:device:basic:1\r\n" +
|
||||||
|
"USN: uuid:Socket-1_0-221438K0100073::urn:schemas-upnp-org:device:basic:1\r\n\r\n";
|
||||||
|
|
||||||
public UpnpListener(BridgeSettingsDescriptor theSettings, BridgeControlDescriptor theControl) {
|
public UpnpListener(BridgeSettingsDescriptor theSettings, BridgeControlDescriptor theControl) {
|
||||||
super();
|
super();
|
||||||
@@ -31,71 +46,124 @@ public class UpnpListener {
|
|||||||
strict = theSettings.isUpnpStrict();
|
strict = theSettings.isUpnpStrict();
|
||||||
traceupnp = theSettings.isTraceupnp();
|
traceupnp = theSettings.isTraceupnp();
|
||||||
bridgeControl = theControl;
|
bridgeControl = theControl;
|
||||||
|
discoveryTemplateLatest = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("resource")
|
||||||
public boolean startListening(){
|
public boolean startListening(){
|
||||||
log.info("UPNP Discovery Listener starting....");
|
log.info("UPNP Discovery Listener starting....");
|
||||||
|
DatagramSocket responseSocket = null;
|
||||||
|
MulticastSocket upnpMulticastSocket = null;
|
||||||
|
Enumeration<NetworkInterface> ifs = null;
|
||||||
|
|
||||||
try (DatagramSocket responseSocket = new DatagramSocket(upnpResponsePort);
|
boolean portLoopControl = true;
|
||||||
MulticastSocket upnpMulticastSocket = new MulticastSocket(Configuration.UPNP_DISCOVERY_PORT);) {
|
int retryCount = 0;
|
||||||
InetSocketAddress socketAddress = new InetSocketAddress(Configuration.UPNP_MULTICAST_ADDRESS, Configuration.UPNP_DISCOVERY_PORT);
|
while(portLoopControl) {
|
||||||
Enumeration<NetworkInterface> ifs = NetworkInterface.getNetworkInterfaces();
|
try {
|
||||||
|
responseSocket = new DatagramSocket(upnpResponsePort);
|
||||||
while (ifs.hasMoreElements()) {
|
if(retryCount > 0)
|
||||||
NetworkInterface xface = ifs.nextElement();
|
log.info("Upnp Response Port issue, found open port: " + upnpResponsePort);
|
||||||
Enumeration<InetAddress> addrs = xface.getInetAddresses();
|
portLoopControl = false;
|
||||||
String name = xface.getName();
|
} catch(SocketException e) {
|
||||||
int IPsPerNic = 0;
|
if(retryCount == 0)
|
||||||
|
log.warn("Upnp Response Port is in use, starting loop to find open port for 20 tries - configured port is: " + upnpResponsePort);
|
||||||
while (addrs.hasMoreElements()) {
|
if(retryCount >= 20) {
|
||||||
InetAddress addr = addrs.nextElement();
|
portLoopControl = false;
|
||||||
if(traceupnp)
|
log.error("Upnp Response Port issue, could not find open port - last port tried: " + upnpResponsePort + " with message: " + e.getMessage());
|
||||||
log.info("Traceupnp: " + name + " ... has addr " + addr);
|
return false;
|
||||||
else
|
|
||||||
log.debug(name + " ... has addr " + addr);
|
|
||||||
if (InetAddressUtils.isIPv4Address(addr.getHostAddress())) {
|
|
||||||
IPsPerNic++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
log.debug("Checking " + name + " to our interface set");
|
}
|
||||||
if (IPsPerNic > 0) {
|
if(portLoopControl) {
|
||||||
|
retryCount++;
|
||||||
|
upnpResponsePort++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
upnpMulticastSocket = new MulticastSocket(Configuration.UPNP_DISCOVERY_PORT);
|
||||||
|
} catch(IOException e){
|
||||||
|
log.error("Upnp Discovery Port is in use, or restricted by admin (try running with sudo or admin privs): " + Configuration.UPNP_DISCOVERY_PORT + " with message: " + e.getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
InetSocketAddress socketAddress = new InetSocketAddress(Configuration.UPNP_MULTICAST_ADDRESS, Configuration.UPNP_DISCOVERY_PORT);
|
||||||
|
try {
|
||||||
|
ifs = NetworkInterface.getNetworkInterfaces();
|
||||||
|
} catch (SocketException e) {
|
||||||
|
log.error("Could not get network interfaces for this machine: " + e.getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (ifs.hasMoreElements()) {
|
||||||
|
NetworkInterface xface = ifs.nextElement();
|
||||||
|
Enumeration<InetAddress> addrs = xface.getInetAddresses();
|
||||||
|
String name = xface.getName();
|
||||||
|
int IPsPerNic = 0;
|
||||||
|
|
||||||
|
while (addrs.hasMoreElements()) {
|
||||||
|
InetAddress addr = addrs.nextElement();
|
||||||
|
if (traceupnp)
|
||||||
|
log.info("Traceupnp: " + name + " ... has addr " + addr);
|
||||||
|
else
|
||||||
|
log.debug(name + " ... has addr " + addr);
|
||||||
|
if (InetAddressUtils.isIPv4Address(addr.getHostAddress())) {
|
||||||
|
IPsPerNic++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.debug("Checking " + name + " to our interface set");
|
||||||
|
if (IPsPerNic > 0) {
|
||||||
|
try {
|
||||||
upnpMulticastSocket.joinGroup(socketAddress, xface);
|
upnpMulticastSocket.joinGroup(socketAddress, xface);
|
||||||
if(traceupnp)
|
if (traceupnp)
|
||||||
log.info("Traceupnp: Adding " + name + " to our interface set");
|
log.info("Traceupnp: Adding " + name + " to our interface set");
|
||||||
else
|
else
|
||||||
log.debug("Adding " + name + " to our interface set");
|
log.debug("Adding " + name + " to our interface set");
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.warn("Multicast join failed for: " + socketAddress.getHostName() + " to interface: "
|
||||||
|
+ xface.getName() + " with message: " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("UPNP Discovery Listener running and ready....");
|
|
||||||
boolean loopControl = true;
|
|
||||||
while(loopControl){ //trigger shutdown here
|
|
||||||
byte[] buf = new byte[1024];
|
|
||||||
DatagramPacket packet = new DatagramPacket(buf, buf.length);
|
|
||||||
upnpMulticastSocket.receive(packet);
|
|
||||||
if(isSSDPDiscovery(packet)){
|
|
||||||
sendUpnpResponse(responseSocket, packet.getAddress(), packet.getPort());
|
|
||||||
}
|
|
||||||
if(bridgeControl.isReinit() || bridgeControl.isStop()) {
|
|
||||||
try {
|
|
||||||
Thread.sleep(1000);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
// noop
|
|
||||||
}
|
|
||||||
loopControl = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
upnpMulticastSocket.close();
|
|
||||||
responseSocket.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
log.error("UpnpListener encountered an error opening sockets. Shutting down", e);
|
|
||||||
}
|
}
|
||||||
if(bridgeControl.isReinit())
|
|
||||||
|
log.info("UPNP Discovery Listener running and ready....");
|
||||||
|
boolean loopControl = true;
|
||||||
|
boolean error = false;
|
||||||
|
while (loopControl) { // trigger shutdown here
|
||||||
|
byte[] buf = new byte[1024];
|
||||||
|
DatagramPacket packet = new DatagramPacket(buf, buf.length);
|
||||||
|
try {
|
||||||
|
upnpMulticastSocket.receive(packet);
|
||||||
|
if (isSSDPDiscovery(packet)) {
|
||||||
|
try {
|
||||||
|
sendUpnpResponse(responseSocket, packet.getAddress(), packet.getPort());
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("UpnpListener encountered an error sending upnp response packet. Shutting down", e);
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("UpnpListener encountered an error reading socket. Shutting down", e);
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
if (error || bridgeControl.isReinit() || bridgeControl.isStop()) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(1000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// noop
|
||||||
|
}
|
||||||
|
loopControl = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
upnpMulticastSocket.close();
|
||||||
|
responseSocket.close();
|
||||||
|
if (bridgeControl.isReinit())
|
||||||
log.info("UPNP Discovery Listener - ended, restart found");
|
log.info("UPNP Discovery Listener - ended, restart found");
|
||||||
if(bridgeControl.isStop())
|
if (bridgeControl.isStop())
|
||||||
log.info("UPNP Discovery Listener - ended, stop found");
|
log.info("UPNP Discovery Listener - ended, stop found");
|
||||||
if(!bridgeControl.isStop()&& !bridgeControl.isReinit())
|
if (!bridgeControl.isStop() && !bridgeControl.isReinit()) {
|
||||||
log.info("UPNP Discovery Listener - ended, error found");
|
log.info("UPNP Discovery Listener - ended, error found");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return bridgeControl.isReinit();
|
return bridgeControl.isReinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,16 +205,12 @@ public class UpnpListener {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
String discoveryTemplate = "HTTP/1.1 200 OK\r\n" +
|
|
||||||
"CACHE-CONTROL: max-age=86400\r\n" +
|
|
||||||
"EXT:\r\n" +
|
|
||||||
"LOCATION: http://%s:%s/description.xml\r\n" +
|
|
||||||
"SERVER: FreeRTOS/6.0.5, UPnP/1.0, IpBridge/0.1\r\n" +
|
|
||||||
"ST: urn:schemas-upnp-org:device:basic:1\r\n" +
|
|
||||||
"USN: uuid:Socket-1_0-221438K0100073::urn:schemas-upnp-org:device:basic:1\r\n\r\n";
|
|
||||||
protected void sendUpnpResponse(DatagramSocket socket, InetAddress requester, int sourcePort) throws IOException {
|
protected void sendUpnpResponse(DatagramSocket socket, InetAddress requester, int sourcePort) throws IOException {
|
||||||
String discoveryResponse = null;
|
String discoveryResponse = null;
|
||||||
discoveryResponse = String.format(discoveryTemplate, responseAddress, httpServerPort);
|
if(discoveryTemplateLatest)
|
||||||
|
discoveryResponse = String.format(discoveryTemplate, responseAddress, httpServerPort);
|
||||||
|
else
|
||||||
|
discoveryResponse = String.format(discoveryTemplateOld, Configuration.UPNP_MULTICAST_ADDRESS, Configuration.UPNP_DISCOVERY_PORT, responseAddress, httpServerPort);
|
||||||
if(traceupnp)
|
if(traceupnp)
|
||||||
log.info("Traceupnp: sendUpnpResponse discovery template with address: " + responseAddress + " and port: " + httpServerPort);
|
log.info("Traceupnp: sendUpnpResponse discovery template with address: " + responseAddress + " and port: " + httpServerPort);
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -15,26 +15,51 @@ public class UpnpSettingsResource {
|
|||||||
|
|
||||||
private BridgeSettingsDescriptor theSettings;
|
private BridgeSettingsDescriptor theSettings;
|
||||||
|
|
||||||
private String hueTemplate = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" + "<root xmlns=\"urn:schemas-upnp-org:device-1-0\">\n"
|
private String hueTemplate = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
|
||||||
+ "<specVersion>\n" + "<major>1</major>\n" + "<minor>0</minor>\n" + "</specVersion>\n"
|
+ "<root xmlns=\"urn:schemas-upnp-org:device-1-0\">\n"
|
||||||
+ "<URLBase>http://%s:%s/</URLBase>\n" + // hostname string
|
+ "<specVersion>\n"
|
||||||
"<device>\n" + "<deviceType>urn:schemas-upnp-org:device:Basic:1</deviceType>\n"
|
+ "<major>1</major>\n"
|
||||||
+ "<friendlyName>HA-Bridge (%s)</friendlyName>\n"
|
+ "<minor>0</minor>\n"
|
||||||
+ "<manufacturer>Royal Philips Electronics</manufacturer>\n"
|
+ "</specVersion>\n"
|
||||||
+ "<manufacturerURL>http://www.bwssystems.com</manufacturerURL>\n"
|
+ "<URLBase>http://%s:%s/</URLBase>\n"
|
||||||
+ "<modelDescription>Hue Emulator for HA bridge</modelDescription>\n"
|
+ "<device>\n"
|
||||||
+ "<modelName>Philips hue bridge 2012</modelName>\n" + "<modelNumber>929000226503</modelNumber>\n"
|
+ "<deviceType>urn:schemas-upnp-org:device:Basic:1</deviceType>\n"
|
||||||
+ "<modelURL>http://www.bwssystems.com/apps.html</modelURL>\n"
|
+ "<friendlyName>Philips hue (%s)</friendlyName>\n"
|
||||||
+ "<serialNumber>0017880ae670</serialNumber>\n"
|
+ "<manufacturer>Royal Philips Electronics</manufacturer>\n"
|
||||||
+ "<UDN>uuid:88f6698f-2c83-4393-bd03-cd54a9f8595</UDN>\n" + "<serviceList>\n" + "<service>\n"
|
+ "<manufacturerURL>http://www.philips.com</manufacturerURL>\n"
|
||||||
+ "<serviceType>(null)</serviceType>\n" + "<serviceId>(null)</serviceId>\n"
|
+ "<modelDescription>Philips hue Personal Wireless Lighting</modelDescription>\n"
|
||||||
+ "<controlURL>(null)</controlURL>\n" + "<eventSubURL>(null)</eventSubURL>\n"
|
+ "<modelName>Philips hue bridge 2015</modelName>\n"
|
||||||
+ "<SCPDURL>(null)</SCPDURL>\n" + "</service>\n" + "</serviceList>\n"
|
+ "<modelNumber>BSB002</modelNumber>\n"
|
||||||
+ "<presentationURL>index.html</presentationURL>\n" + "<iconList>\n" + "<icon>\n"
|
+ "<modelURL>http://www.meethue.com</modelURL>\n"
|
||||||
+ "<mimetype>image/png</mimetype>\n" + "<height>48</height>\n" + "<width>48</width>\n"
|
+ "<serialNumber>0017880ae670</serialNumber>\n"
|
||||||
+ "<depth>24</depth>\n" + "<url>hue_logo_0.png</url>\n" + "</icon>\n" + "<icon>\n"
|
+ "<UDN>uuid:2f402f80-da50-11e1-9b23-001788102201</UDN>\n"
|
||||||
+ "<mimetype>image/png</mimetype>\n" + "<height>120</height>\n" + "<width>120</width>\n"
|
+ "<serviceList>\n"
|
||||||
+ "<depth>24</depth>\n" + "<url>hue_logo_3.png</url>\n" + "</icon>\n" + "</iconList>\n" + "</device>\n"
|
+ "<service>\n"
|
||||||
|
+ "<serviceType>(null)</serviceType>\n"
|
||||||
|
+ "<serviceId>(null)</serviceId>\n"
|
||||||
|
+ "<controlURL>(null)</controlURL>\n"
|
||||||
|
+ "<eventSubURL>(null)</eventSubURL>\n"
|
||||||
|
+ "<SCPDURL>(null)</SCPDURL>\n"
|
||||||
|
+ "</service>\n"
|
||||||
|
+ "</serviceList>\n"
|
||||||
|
+ "<presentationURL>index.html</presentationURL>\n"
|
||||||
|
+ "<iconList>\n"
|
||||||
|
+ "<icon>\n"
|
||||||
|
+ "<mimetype>image/png</mimetype>\n"
|
||||||
|
+ "<height>48</height>\n"
|
||||||
|
+ "<width>48</width>\n"
|
||||||
|
+ "<depth>24</depth>\n"
|
||||||
|
+ "<url>hue_logo_0.png</url>\n"
|
||||||
|
+ "</icon>\n"
|
||||||
|
+ "<icon>\n"
|
||||||
|
+ "<mimetype>image/png</mimetype>\n"
|
||||||
|
+ "<height>120</height>\n"
|
||||||
|
+ "<width>120</width>\n"
|
||||||
|
+ "<depth>24</depth>\n"
|
||||||
|
+ "<url>hue_logo_3.png</url>\n"
|
||||||
|
+ "</icon>\n"
|
||||||
|
+ "</iconList>\n"
|
||||||
|
+ "</device>\n"
|
||||||
+ "</root>\n";
|
+ "</root>\n";
|
||||||
|
|
||||||
public UpnpSettingsResource(BridgeSettingsDescriptor theBridgeSettings) {
|
public UpnpSettingsResource(BridgeSettingsDescriptor theBridgeSettings) {
|
||||||
@@ -47,9 +72,9 @@ public class UpnpSettingsResource {
|
|||||||
// http://ip_adress:port/description.xml which returns the xml configuration for the hue emulator
|
// http://ip_adress:port/description.xml which returns the xml configuration for the hue emulator
|
||||||
get("/description.xml", "application/xml; charset=utf-8", (request, response) -> {
|
get("/description.xml", "application/xml; charset=utf-8", (request, response) -> {
|
||||||
if(theSettings.isTraceupnp())
|
if(theSettings.isTraceupnp())
|
||||||
log.info("Traceupnp: upnp device settings requested: " + request.params(":id") + " from " + request.ip() + ":" + request.port());
|
log.info("Traceupnp: upnp device settings requested: " + " from " + request.ip() + ":" + request.port());
|
||||||
else
|
else
|
||||||
log.debug("upnp device settings requested: " + request.params(":id") + " from " + request.ip() + ":" + request.port());
|
log.debug("upnp device settings requested: " + " from " + request.ip() + ":" + request.port());
|
||||||
String portNumber = Integer.toString(request.port());
|
String portNumber = Integer.toString(request.port());
|
||||||
String filledTemplate = null;
|
String filledTemplate = null;
|
||||||
filledTemplate = String.format(hueTemplate, theSettings.getUpnpConfigAddress(), portNumber, theSettings.getUpnpConfigAddress());
|
filledTemplate = String.format(hueTemplate, theSettings.getUpnpConfigAddress(), portNumber, theSettings.getUpnpConfigAddress());
|
||||||
@@ -72,5 +97,17 @@ public class UpnpSettingsResource {
|
|||||||
|
|
||||||
return filledTemplate;
|
return filledTemplate;
|
||||||
} );
|
} );
|
||||||
|
// http://ip_adress:port/favicon.ico
|
||||||
|
get("/favicon.ico", "application/xml; charset=utf-8", (request, response) -> {
|
||||||
|
return "";
|
||||||
|
} );
|
||||||
|
// http://ip_adress:port/hue_logo_0.png
|
||||||
|
get("/hue_logo_0.png", "application/xml; charset=utf-8", (request, response) -> {
|
||||||
|
return "";
|
||||||
|
} );
|
||||||
|
// http://ip_adress:port/hue_logo_3.png
|
||||||
|
get("/hue_logo_3.png", "application/xml; charset=utf-8", (request, response) -> {
|
||||||
|
return "";
|
||||||
|
} );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
17
src/main/java/com/bwssystems/hal/DeviceElements.java
Normal file
17
src/main/java/com/bwssystems/hal/DeviceElements.java
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
package com.bwssystems.hal;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
public class DeviceElements {
|
||||||
|
@SerializedName(value="DeviceElements", alternate={"SceneElements", "GroupElements", "HVACElements", "MacroElements", "IrElements", "IrButtons"})
|
||||||
|
private List<DeviceName> DeviceElements;
|
||||||
|
|
||||||
|
public List<DeviceName> getDeviceElements() {
|
||||||
|
return DeviceElements;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeviceElements(List<DeviceName> deviceElements) {
|
||||||
|
DeviceElements = deviceElements;
|
||||||
|
}
|
||||||
|
}
|
||||||
17
src/main/java/com/bwssystems/hal/DeviceName.java
Normal file
17
src/main/java/com/bwssystems/hal/DeviceName.java
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
package com.bwssystems.hal;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
public class DeviceName {
|
||||||
|
@SerializedName(value="DeviceName", alternate={"SceneName", "GroupName", "HVACName", "MacroName", "IrName", "IrButton"})
|
||||||
|
private String DeviceName;
|
||||||
|
|
||||||
|
public String getDeviceName() {
|
||||||
|
return DeviceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeviceName(String deviceName) {
|
||||||
|
DeviceName = deviceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
39
src/main/java/com/bwssystems/hal/HalDevice.java
Normal file
39
src/main/java/com/bwssystems/hal/HalDevice.java
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
package com.bwssystems.hal;
|
||||||
|
|
||||||
|
public class HalDevice {
|
||||||
|
private String haldevicetype;
|
||||||
|
private String haldevicename;
|
||||||
|
private String haladdress;
|
||||||
|
private String halname;
|
||||||
|
private DeviceElements buttons;
|
||||||
|
public String getHaldevicetype() {
|
||||||
|
return haldevicetype;
|
||||||
|
}
|
||||||
|
public void setHaldevicetype(String haldevicetype) {
|
||||||
|
this.haldevicetype = haldevicetype;
|
||||||
|
}
|
||||||
|
public String getHaldevicename() {
|
||||||
|
return haldevicename;
|
||||||
|
}
|
||||||
|
public void setHaldevicename(String haldevicename) {
|
||||||
|
this.haldevicename = haldevicename;
|
||||||
|
}
|
||||||
|
public String getHaladdress() {
|
||||||
|
return haladdress;
|
||||||
|
}
|
||||||
|
public void setHaladdress(String haladdress) {
|
||||||
|
this.haladdress = haladdress;
|
||||||
|
}
|
||||||
|
public String getHalname() {
|
||||||
|
return halname;
|
||||||
|
}
|
||||||
|
public void setHalname(String halname) {
|
||||||
|
this.halname = halname;
|
||||||
|
}
|
||||||
|
public DeviceElements getButtons() {
|
||||||
|
return buttons;
|
||||||
|
}
|
||||||
|
public void setButtons(DeviceElements buttons) {
|
||||||
|
this.buttons = buttons;
|
||||||
|
}
|
||||||
|
}
|
||||||
113
src/main/java/com/bwssystems/hal/HalHome.java
Normal file
113
src/main/java/com/bwssystems/hal/HalHome.java
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
package com.bwssystems.hal;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.bwssystems.HABridge.BridgeSettingsDescriptor;
|
||||||
|
import com.bwssystems.HABridge.NamedIP;
|
||||||
|
|
||||||
|
public class HalHome {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(HalHome.class);
|
||||||
|
private Map<String, HalInfo> hals;
|
||||||
|
|
||||||
|
public HalHome(BridgeSettingsDescriptor bridgeSettings) {
|
||||||
|
super();
|
||||||
|
hals = new HashMap<String, HalInfo>();
|
||||||
|
if(!bridgeSettings.isValidHal())
|
||||||
|
return;
|
||||||
|
Iterator<NamedIP> theList = bridgeSettings.getHaladdress().getDevices().iterator();
|
||||||
|
while(theList.hasNext()) {
|
||||||
|
NamedIP aHal = theList.next();
|
||||||
|
try {
|
||||||
|
hals.put(aHal.getName(), new HalInfo(aHal, bridgeSettings.getHaltoken()));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Cannot get harmony client (" + aHal.getName() + ") setup, Exiting with message: " + e.getMessage(), e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<HalDevice> getDevices() {
|
||||||
|
log.debug("consolidating devices for hues");
|
||||||
|
List<HalDevice> theResponse = null;
|
||||||
|
Iterator<String> keys = hals.keySet().iterator();
|
||||||
|
List<HalDevice> deviceList = new ArrayList<HalDevice>();
|
||||||
|
while(keys.hasNext()) {
|
||||||
|
String key = keys.next();
|
||||||
|
theResponse = hals.get(key).getLights();
|
||||||
|
if(theResponse != null)
|
||||||
|
addHalDevices(deviceList, theResponse, key);
|
||||||
|
else {
|
||||||
|
log.warn("Cannot get lights for Hal with name: " + key + ", skipping this HAL.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
theResponse = hals.get(key).getAppliances();
|
||||||
|
if(theResponse != null)
|
||||||
|
addHalDevices(deviceList, theResponse, key);
|
||||||
|
else
|
||||||
|
log.warn("Cannot get appliances for Hal with name: " + key);
|
||||||
|
theResponse = hals.get(key).getTheatre();
|
||||||
|
if(theResponse != null)
|
||||||
|
addHalDevices(deviceList, theResponse, key);
|
||||||
|
else
|
||||||
|
log.warn("Cannot get theatre for Hal with name: " + key);
|
||||||
|
theResponse = hals.get(key).getCustom();
|
||||||
|
if(theResponse != null)
|
||||||
|
addHalDevices(deviceList, theResponse, key);
|
||||||
|
else
|
||||||
|
log.warn("Cannot get custom for Hal with name: " + key);
|
||||||
|
theResponse = hals.get(key).getHVAC();
|
||||||
|
if(theResponse != null)
|
||||||
|
addHalDevices(deviceList, theResponse, key);
|
||||||
|
else
|
||||||
|
log.warn("Cannot get HVAC for Hal with name: " + key);
|
||||||
|
theResponse = hals.get(key).getHome(key);
|
||||||
|
if(theResponse != null)
|
||||||
|
addHalDevices(deviceList, theResponse, key);
|
||||||
|
else
|
||||||
|
log.warn("Cannot get Homes for Hal with name: " + key);
|
||||||
|
theResponse = hals.get(key).getGroups();
|
||||||
|
if(theResponse != null)
|
||||||
|
addHalDevices(deviceList, theResponse, key);
|
||||||
|
else
|
||||||
|
log.warn("Cannot get Groups for Hal with name: " + key);
|
||||||
|
theResponse = hals.get(key).getMacros();
|
||||||
|
if(theResponse != null)
|
||||||
|
addHalDevices(deviceList, theResponse, key);
|
||||||
|
else
|
||||||
|
log.warn("Cannot get Macros for Hal with name: " + key);
|
||||||
|
theResponse = hals.get(key).getScenes();
|
||||||
|
if(theResponse != null)
|
||||||
|
addHalDevices(deviceList, theResponse, key);
|
||||||
|
else
|
||||||
|
log.warn("Cannot get Scenes for Hal with name: " + key);
|
||||||
|
theResponse = hals.get(key).getButtons();
|
||||||
|
if(theResponse != null)
|
||||||
|
addHalDevices(deviceList, theResponse, key);
|
||||||
|
else
|
||||||
|
log.warn("Cannot get Buttons for Hal with name: " + key);
|
||||||
|
}
|
||||||
|
return deviceList;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Boolean addHalDevices(List<HalDevice> theDeviceList, List<HalDevice> theSourceList, String theKey) {
|
||||||
|
Iterator<HalDevice> devices = theSourceList.iterator();
|
||||||
|
while(devices.hasNext()) {
|
||||||
|
HalDevice theDevice = devices.next();
|
||||||
|
HalDevice aNewHalDevice = new HalDevice();
|
||||||
|
aNewHalDevice.setHaldevicetype(theDevice.getHaldevicetype());
|
||||||
|
aNewHalDevice.setHaldevicename(theDevice.getHaldevicename());
|
||||||
|
aNewHalDevice.setButtons(theDevice.getButtons());
|
||||||
|
aNewHalDevice.setHaladdress(hals.get(theKey).getHalAddress().getIp());
|
||||||
|
aNewHalDevice.setHalname(theKey);
|
||||||
|
theDeviceList.add(aNewHalDevice);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
206
src/main/java/com/bwssystems/hal/HalInfo.java
Normal file
206
src/main/java/com/bwssystems/hal/HalInfo.java
Normal file
@@ -0,0 +1,206 @@
|
|||||||
|
package com.bwssystems.hal;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.http.HttpResponse;
|
||||||
|
import org.apache.http.client.HttpClient;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.impl.client.HttpClients;
|
||||||
|
import org.apache.http.util.EntityUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.bwssystems.HABridge.NamedIP;
|
||||||
|
import com.bwssystems.util.TextStringFormatter;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
|
public class HalInfo {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(HalInfo.class);
|
||||||
|
private static final String DEVICE_REQUEST = "/DeviceData!DeviceCmd=GetNames!DeviceType=";
|
||||||
|
private static final String HVAC_REQUEST = "/HVACData!HVACCmd=GetNames";
|
||||||
|
private static final String GROUP_REQUEST = "/GroupData!GroupCmd=GetNames";
|
||||||
|
private static final String MACRO_REQUEST = "/MacroData!MacroCmd=GetNames";
|
||||||
|
private static final String SCENE_REQUEST = "/SceneData!SceneCmd=GetNames";
|
||||||
|
private static final String IRDATA_REQUEST = "/IrData!IRCmd=GetNames";
|
||||||
|
private static final String IRBUTTON_REQUEST = "/IrData!IRCmd=GetButtons!IrDevice=";
|
||||||
|
private static final String TOKEN_REQUEST = "?Token=";
|
||||||
|
private static final String LIGHT_REQUEST = "Light";
|
||||||
|
private static final String APPL_REQUEST = "Appl";
|
||||||
|
// private static final String VIDEO_REQUEST = "Video";
|
||||||
|
private static final String THEATRE_REQUEST = "Theatre";
|
||||||
|
private static final String CUSTOM_REQUEST = "Custom";
|
||||||
|
private static final String HVAC_TYPE = "HVAC";
|
||||||
|
private static final String HOME_TYPE = "Home";
|
||||||
|
private static final String GROUP_TYPE = "Group";
|
||||||
|
private static final String MACRO_TYPE = "Macro";
|
||||||
|
private static final String SCENE_TYPE = "Scene";
|
||||||
|
private static final String IRDATA_TYPE = "IrData";
|
||||||
|
private HttpClient httpClient;
|
||||||
|
private NamedIP halAddress;
|
||||||
|
private String theToken;
|
||||||
|
|
||||||
|
public HalInfo(NamedIP addressName, String aGivenToken) {
|
||||||
|
super();
|
||||||
|
httpClient = HttpClients.createDefault();
|
||||||
|
halAddress = addressName;
|
||||||
|
theToken = aGivenToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<HalDevice> getLights() {
|
||||||
|
return getHalDevices(DEVICE_REQUEST + LIGHT_REQUEST + TOKEN_REQUEST, LIGHT_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<HalDevice> getAppliances() {
|
||||||
|
return getHalDevices(DEVICE_REQUEST + APPL_REQUEST + TOKEN_REQUEST, APPL_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<HalDevice> getTheatre() {
|
||||||
|
return getHalDevices(DEVICE_REQUEST + THEATRE_REQUEST + TOKEN_REQUEST, THEATRE_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<HalDevice> getCustom() {
|
||||||
|
return getHalDevices(DEVICE_REQUEST + CUSTOM_REQUEST + TOKEN_REQUEST, CUSTOM_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<HalDevice> getHVAC() {
|
||||||
|
return getHalDevices(HVAC_REQUEST + TOKEN_REQUEST, HVAC_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<HalDevice> getGroups() {
|
||||||
|
return getHalDevices(GROUP_REQUEST + TOKEN_REQUEST, GROUP_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<HalDevice> getMacros() {
|
||||||
|
return getHalDevices(MACRO_REQUEST + TOKEN_REQUEST, MACRO_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<HalDevice> getScenes() {
|
||||||
|
return getHalDevices(SCENE_REQUEST + TOKEN_REQUEST, SCENE_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<HalDevice> getButtons() {
|
||||||
|
List<HalDevice> irDataDevices = getHalDevices(IRDATA_REQUEST + TOKEN_REQUEST, IRDATA_TYPE);
|
||||||
|
|
||||||
|
return getDeviceButtons(irDataDevices);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<HalDevice> getHome(String theDeviceName) {
|
||||||
|
List<HalDevice> deviceList = null;
|
||||||
|
deviceList = new ArrayList<HalDevice>();
|
||||||
|
HalDevice aNewHalDevice = new HalDevice();
|
||||||
|
aNewHalDevice.setHaldevicetype(HOME_TYPE);
|
||||||
|
aNewHalDevice.setHaldevicename(theDeviceName);
|
||||||
|
deviceList.add(aNewHalDevice);
|
||||||
|
return deviceList;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<HalDevice> getHalDevices(String apiType, String deviceType) {
|
||||||
|
DeviceElements theHalApiResponse = null;
|
||||||
|
List<HalDevice> deviceList = null;
|
||||||
|
|
||||||
|
String theUrl = null;
|
||||||
|
String theData;
|
||||||
|
theUrl = "http://" + halAddress.getIp() + apiType + theToken;
|
||||||
|
theData = doHttpGETRequest(theUrl);
|
||||||
|
if(theData != null) {
|
||||||
|
log.debug("GET " + deviceType + " HalApiResponse - data: " + theData);
|
||||||
|
theHalApiResponse = new Gson().fromJson(theData, DeviceElements.class);
|
||||||
|
if(theHalApiResponse.getDeviceElements() == null) {
|
||||||
|
StatusDescription theStatus = new Gson().fromJson(theData, StatusDescription.class);
|
||||||
|
if(theStatus.getStatus() == null) {
|
||||||
|
log.warn("Cannot get an devices for type " + deviceType + " for hal " + halAddress.getName() + " as response is not parsable.");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log.warn("Cannot get an devices for type " + deviceType + " for hal " + halAddress.getName() + ". Status: " + theStatus.getStatus() + ", with description: " + theStatus.getDescription());
|
||||||
|
}
|
||||||
|
return deviceList;
|
||||||
|
}
|
||||||
|
deviceList = new ArrayList<HalDevice>();
|
||||||
|
|
||||||
|
Iterator<DeviceName> theDeviceNames = theHalApiResponse.getDeviceElements().iterator();
|
||||||
|
while(theDeviceNames.hasNext()) {
|
||||||
|
DeviceName theDevice = theDeviceNames.next();
|
||||||
|
HalDevice aNewHalDevice = new HalDevice();
|
||||||
|
aNewHalDevice.setHaldevicetype(deviceType);
|
||||||
|
aNewHalDevice.setHaldevicename(theDevice.getDeviceName());
|
||||||
|
deviceList.add(aNewHalDevice);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log.warn("Get Hal device types " + deviceType + " for " + halAddress.getName() + " - returned null, no data.");
|
||||||
|
}
|
||||||
|
return deviceList;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<HalDevice> getDeviceButtons(List<HalDevice> theIrDevices) {
|
||||||
|
DeviceElements theHalApiResponse = null;
|
||||||
|
List<HalDevice> deviceList = null;
|
||||||
|
|
||||||
|
String theUrl = null;
|
||||||
|
String theData;
|
||||||
|
if(theIrDevices == null)
|
||||||
|
return null;
|
||||||
|
Iterator<HalDevice> theHalDevices = theIrDevices.iterator();
|
||||||
|
deviceList = new ArrayList<HalDevice>();
|
||||||
|
while (theHalDevices.hasNext()) {
|
||||||
|
HalDevice theHalDevice = theHalDevices.next();
|
||||||
|
theUrl = "http://" + halAddress.getIp() + IRBUTTON_REQUEST + TextStringFormatter.forQuerySpaceUrl(theHalDevice.getHaldevicename()) + TOKEN_REQUEST + theToken;
|
||||||
|
theData = doHttpGETRequest(theUrl);
|
||||||
|
if (theData != null) {
|
||||||
|
log.debug("GET IrData for IR Device " + theHalDevice.getHaldevicename() + " HalApiResponse - data: " + theData);
|
||||||
|
theHalApiResponse = new Gson().fromJson(theData, DeviceElements.class);
|
||||||
|
if (theHalApiResponse.getDeviceElements() == null) {
|
||||||
|
StatusDescription theStatus = new Gson().fromJson(theData, StatusDescription.class);
|
||||||
|
if (theStatus.getStatus() == null) {
|
||||||
|
log.warn("Cannot get buttons for IR Device " + theHalDevice.getHaldevicename() + " for hal "
|
||||||
|
+ halAddress.getName() + " as response is not parsable.");
|
||||||
|
} else {
|
||||||
|
log.warn("Cannot get buttons for IR Device " + theHalDevice.getHaldevicename() + " for hal "
|
||||||
|
+ halAddress.getName() + ". Status: " + theStatus.getStatus() + ", with description: "
|
||||||
|
+ theStatus.getDescription());
|
||||||
|
}
|
||||||
|
return deviceList;
|
||||||
|
}
|
||||||
|
theHalDevice.setButtons(theHalApiResponse);
|
||||||
|
deviceList.add(theHalDevice);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
log.warn("Get Hal buttons for IR Device " + theHalDevice.getHaldevicename() + " for "
|
||||||
|
+ halAddress.getName() + " - returned null, no data.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return deviceList;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function executes the url against the hal
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NamedIP getHalAddress() {
|
||||||
|
return halAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHalAddress(NamedIP halAddress) {
|
||||||
|
this.halAddress = halAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
18
src/main/java/com/bwssystems/hal/StatusDescription.java
Normal file
18
src/main/java/com/bwssystems/hal/StatusDescription.java
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package com.bwssystems.hal;
|
||||||
|
|
||||||
|
public class StatusDescription {
|
||||||
|
private String Status;
|
||||||
|
private String Description;
|
||||||
|
public String getStatus() {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
public void setStatus(String status) {
|
||||||
|
Status = status;
|
||||||
|
}
|
||||||
|
public String getDescription() {
|
||||||
|
return Description;
|
||||||
|
}
|
||||||
|
public void setDescription(String description) {
|
||||||
|
Description = description;
|
||||||
|
}
|
||||||
|
}
|
||||||
35
src/main/java/com/bwssystems/hue/HueDevice.java
Normal file
35
src/main/java/com/bwssystems/hue/HueDevice.java
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
package com.bwssystems.hue;
|
||||||
|
|
||||||
|
import com.bwssystems.HABridge.api.hue.DeviceResponse;
|
||||||
|
|
||||||
|
|
||||||
|
public class HueDevice {
|
||||||
|
private DeviceResponse device;
|
||||||
|
private String huedeviceid;
|
||||||
|
private String hueaddress;
|
||||||
|
private String huename;
|
||||||
|
public DeviceResponse getDevice() {
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
public void setDevice(DeviceResponse adevice) {
|
||||||
|
this.device = adevice;
|
||||||
|
}
|
||||||
|
public String getHuedeviceid() {
|
||||||
|
return huedeviceid;
|
||||||
|
}
|
||||||
|
public void setHuedeviceid(String huedeviceid) {
|
||||||
|
this.huedeviceid = huedeviceid;
|
||||||
|
}
|
||||||
|
public String getHueaddress() {
|
||||||
|
return hueaddress;
|
||||||
|
}
|
||||||
|
public void setHueaddress(String ahueaddress) {
|
||||||
|
this.hueaddress = ahueaddress;
|
||||||
|
}
|
||||||
|
public String getHuename() {
|
||||||
|
return huename;
|
||||||
|
}
|
||||||
|
public void setHuename(String ahuename) {
|
||||||
|
this.huename = ahuename;
|
||||||
|
}
|
||||||
|
}
|
||||||
18
src/main/java/com/bwssystems/hue/HueDeviceIdentifier.java
Normal file
18
src/main/java/com/bwssystems/hue/HueDeviceIdentifier.java
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package com.bwssystems.hue;
|
||||||
|
|
||||||
|
public class HueDeviceIdentifier {
|
||||||
|
private String ipAddress;
|
||||||
|
private String deviceId;
|
||||||
|
public String getIpAddress() {
|
||||||
|
return ipAddress;
|
||||||
|
}
|
||||||
|
public void setIpAddress(String ipAddress) {
|
||||||
|
this.ipAddress = ipAddress;
|
||||||
|
}
|
||||||
|
public String getDeviceId() {
|
||||||
|
return deviceId;
|
||||||
|
}
|
||||||
|
public void setDeviceId(String deviceId) {
|
||||||
|
this.deviceId = deviceId;
|
||||||
|
}
|
||||||
|
}
|
||||||
5
src/main/java/com/bwssystems/hue/HueErrorStringSet.java
Normal file
5
src/main/java/com/bwssystems/hue/HueErrorStringSet.java
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
package com.bwssystems.hue;
|
||||||
|
|
||||||
|
public interface HueErrorStringSet {
|
||||||
|
public void setErrorString(String anError);
|
||||||
|
}
|
||||||
73
src/main/java/com/bwssystems/hue/HueHome.java
Normal file
73
src/main/java/com/bwssystems/hue/HueHome.java
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
package com.bwssystems.hue;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.bwssystems.HABridge.BridgeSettingsDescriptor;
|
||||||
|
import com.bwssystems.HABridge.NamedIP;
|
||||||
|
import com.bwssystems.HABridge.api.hue.DeviceResponse;
|
||||||
|
import com.bwssystems.HABridge.api.hue.HueApiResponse;
|
||||||
|
|
||||||
|
public class HueHome {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(HueHome.class);
|
||||||
|
private Map<String, HueInfo> hues;
|
||||||
|
private String theHUERegisteredUser;
|
||||||
|
|
||||||
|
public HueHome(BridgeSettingsDescriptor bridgeSettings) {
|
||||||
|
hues = new HashMap<String, HueInfo>();
|
||||||
|
if(!bridgeSettings.isValidHue())
|
||||||
|
return;
|
||||||
|
Iterator<NamedIP> theList = bridgeSettings.getHueaddress().getDevices().iterator();
|
||||||
|
while(theList.hasNext()) {
|
||||||
|
NamedIP aHue = theList.next();
|
||||||
|
hues.put(aHue.getName(), new HueInfo(aHue, this));
|
||||||
|
}
|
||||||
|
theHUERegisteredUser = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<HueDevice> getDevices() {
|
||||||
|
log.debug("consolidating devices for hues");
|
||||||
|
Iterator<String> keys = hues.keySet().iterator();
|
||||||
|
ArrayList<HueDevice> deviceList = new ArrayList<HueDevice>();
|
||||||
|
while(keys.hasNext()) {
|
||||||
|
String key = keys.next();
|
||||||
|
HueApiResponse theResponse = hues.get(key).getHueApiResponse();
|
||||||
|
if(theResponse != null) {
|
||||||
|
Map<String, DeviceResponse> theDevices = theResponse.getLights();
|
||||||
|
if(theDevices != null) {
|
||||||
|
Iterator<String> deviceKeys = theDevices.keySet().iterator();
|
||||||
|
while(deviceKeys.hasNext()) {
|
||||||
|
String theDeviceKey = deviceKeys.next();
|
||||||
|
HueDevice aNewHueDevice = new HueDevice();
|
||||||
|
aNewHueDevice.setDevice(theDevices.get(theDeviceKey));
|
||||||
|
aNewHueDevice.setHuedeviceid(theDeviceKey);
|
||||||
|
aNewHueDevice.setHueaddress(hues.get(key).getHueAddress().getIp());
|
||||||
|
aNewHueDevice.setHuename(key);
|
||||||
|
deviceList.add(aNewHueDevice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
deviceList = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
log.warn("Cannot get lights for Hue with name: " + key);
|
||||||
|
}
|
||||||
|
return deviceList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTheHUERegisteredUser() {
|
||||||
|
return theHUERegisteredUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTheHUERegisteredUser(String theHUERegisteredUser) {
|
||||||
|
this.theHUERegisteredUser = theHUERegisteredUser;
|
||||||
|
}
|
||||||
|
}
|
||||||
111
src/main/java/com/bwssystems/hue/HueInfo.java
Normal file
111
src/main/java/com/bwssystems/hue/HueInfo.java
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
package com.bwssystems.hue;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import org.apache.http.HttpResponse;
|
||||||
|
import org.apache.http.client.HttpClient;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.impl.client.HttpClients;
|
||||||
|
import org.apache.http.util.EntityUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.bwssystems.HABridge.NamedIP;
|
||||||
|
import com.bwssystems.HABridge.api.hue.HueApiResponse;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
|
|
||||||
|
public class HueInfo implements HueErrorStringSet {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(HueInfo.class);
|
||||||
|
private HttpClient httpClient;
|
||||||
|
private NamedIP hueAddress;
|
||||||
|
private String theUser;
|
||||||
|
private HueHome theHueHome;
|
||||||
|
private String errorString = null;
|
||||||
|
|
||||||
|
public HueInfo(NamedIP addressName, HueHome aHueHome) {
|
||||||
|
super();
|
||||||
|
httpClient = HttpClients.createDefault();
|
||||||
|
hueAddress = addressName;
|
||||||
|
theUser = "habridge";
|
||||||
|
theHueHome = aHueHome;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HueApiResponse getHueApiResponse() {
|
||||||
|
HueApiResponse theHueApiResponse = null;
|
||||||
|
|
||||||
|
String theUrl = "http://" + hueAddress.getIp() + HueUtil.HUE_REQUEST + "/" + theUser;
|
||||||
|
String theData;
|
||||||
|
boolean loopControl = true;
|
||||||
|
int retryCount = 0;
|
||||||
|
while(loopControl) {
|
||||||
|
if(retryCount > 3) {
|
||||||
|
log.warn("Max Retry reached to get Hue data from " + hueAddress.getName());
|
||||||
|
loopControl = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
theUrl = "http://" + hueAddress.getIp() + HueUtil.HUE_REQUEST + "/" + theUser;
|
||||||
|
theData = doHttpGETRequest(theUrl);
|
||||||
|
if(theData != null) {
|
||||||
|
log.debug("GET HueApiResponse - data: " + theData);
|
||||||
|
if(theData.contains("[{\"error\":")) {
|
||||||
|
if(theData.contains("unauthorized user")) {
|
||||||
|
theUser = HueUtil.registerWithHue(httpClient, hueAddress.getIp(), hueAddress.getName(), theHueHome.getTheHUERegisteredUser(), this);
|
||||||
|
if(theUser == null) {
|
||||||
|
log.warn("Register to Hue for " + hueAddress.getName() + " returned error: " + errorString);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
theHueHome.setTheHUERegisteredUser(theUser);
|
||||||
|
retryCount++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log.warn("GET HueApiResponse for " + hueAddress.getName() + " - returned error: " + theData);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
theHueApiResponse = new Gson().fromJson(theData, HueApiResponse.class);
|
||||||
|
log.debug("GET HueApiResponse for " + hueAddress.getName() + " - Gson parse - name: " + theHueApiResponse.getConfig().getName() + ", mac addr: " + theHueApiResponse.getConfig().getMac());
|
||||||
|
loopControl = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log.warn("GET HueApiResponse for " + hueAddress.getName() + " - returned null, no data.");
|
||||||
|
loopControl = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return theHueApiResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function executes the url against the vera
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NamedIP getHueAddress() {
|
||||||
|
return hueAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHueAddress(NamedIP hueAddress) {
|
||||||
|
this.hueAddress = hueAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setErrorString(String anError) {
|
||||||
|
errorString = anError;
|
||||||
|
}
|
||||||
|
}
|
||||||
55
src/main/java/com/bwssystems/hue/HueUtil.java
Normal file
55
src/main/java/com/bwssystems/hue/HueUtil.java
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
package com.bwssystems.hue;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.apache.http.HttpResponse;
|
||||||
|
import org.apache.http.client.HttpClient;
|
||||||
|
import org.apache.http.client.methods.HttpPost;
|
||||||
|
import org.apache.http.entity.ContentType;
|
||||||
|
import org.apache.http.entity.StringEntity;
|
||||||
|
import org.apache.http.util.EntityUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.bwssystems.HABridge.api.SuccessUserResponse;
|
||||||
|
import com.bwssystems.HABridge.api.UserCreateRequest;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
|
public class HueUtil {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(HueUtil.class);
|
||||||
|
public static final String HUE_REQUEST = "/api";
|
||||||
|
|
||||||
|
public static final String registerWithHue(HttpClient anHttpClient, String ipAddress, String aName, String theUser, HueErrorStringSet errorStringSet) {
|
||||||
|
UserCreateRequest theLogin = new UserCreateRequest();
|
||||||
|
theLogin.setDevicetype("HABridge#MyMachine");
|
||||||
|
HttpPost postRequest = new HttpPost("http://" + ipAddress + HUE_REQUEST);
|
||||||
|
ContentType parsedContentType = ContentType.parse("application/json");
|
||||||
|
StringEntity requestBody = new StringEntity(new Gson().toJson(theLogin), parsedContentType);
|
||||||
|
HttpResponse response = null;
|
||||||
|
postRequest.setEntity(requestBody);
|
||||||
|
try {
|
||||||
|
response = anHttpClient.execute(postRequest);
|
||||||
|
log.debug("POST execute on URL responded: " + response.getStatusLine().getStatusCode());
|
||||||
|
if(response.getStatusLine().getStatusCode() >= 200 && response.getStatusLine().getStatusCode() < 300){
|
||||||
|
String theBody = EntityUtils.toString(response.getEntity());
|
||||||
|
log.debug("registerWithHue response data: " + theBody);
|
||||||
|
if(theBody.contains("[{\"error\":")) {
|
||||||
|
if(theBody.contains("link button not")) {
|
||||||
|
log.warn("registerWithHue needs link button pressed on HUE bridge: " + aName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
log.warn("registerWithHue returned an unexpected error: " + theBody);
|
||||||
|
errorStringSet.setErrorString(theBody);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SuccessUserResponse[] theResponses = new Gson().fromJson(theBody, SuccessUserResponse[].class); //read content for data, SuccessUserResponse[].class);
|
||||||
|
theUser = theResponses[0].getSuccess().getUsername();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EntityUtils.consume(response.getEntity()); //close out inputstream ignore content
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.warn("Error logging into HUE: IOException in log", e);
|
||||||
|
}
|
||||||
|
return theUser;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
package com.bwssystems.util;
|
|
||||||
|
|
||||||
import java.text.StringCharacterIterator;
|
|
||||||
|
|
||||||
public final class JsonFreeTextStringFormatter {
|
|
||||||
private JsonFreeTextStringFormatter(){
|
|
||||||
//empty - prevent construction
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String forJSON(String aText){
|
|
||||||
final StringBuilder result = new StringBuilder();
|
|
||||||
StringCharacterIterator iterator = new StringCharacterIterator(aText);
|
|
||||||
char character = iterator.current();
|
|
||||||
while (character != StringCharacterIterator.DONE){
|
|
||||||
if( character == '\"' ){
|
|
||||||
result.append("\\\"");
|
|
||||||
}
|
|
||||||
else if(character == '\\'){
|
|
||||||
result.append("\\\\");
|
|
||||||
}
|
|
||||||
else if(character == '/'){
|
|
||||||
result.append("\\/");
|
|
||||||
}
|
|
||||||
else if(character == '\b'){
|
|
||||||
result.append("\\b");
|
|
||||||
}
|
|
||||||
else if(character == '\f'){
|
|
||||||
result.append("\\f");
|
|
||||||
}
|
|
||||||
else if(character == '\n'){
|
|
||||||
result.append("\\n");
|
|
||||||
}
|
|
||||||
else if(character == '\r'){
|
|
||||||
result.append("\\r");
|
|
||||||
}
|
|
||||||
else if(character == '\t'){
|
|
||||||
result.append("\\t");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
//the char is not a special one
|
|
||||||
//add it to the result as is
|
|
||||||
result.append(character);
|
|
||||||
}
|
|
||||||
character = iterator.next();
|
|
||||||
}
|
|
||||||
return result.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
262
src/main/java/com/bwssystems/util/TextStringFormatter.java
Normal file
262
src/main/java/com/bwssystems/util/TextStringFormatter.java
Normal file
@@ -0,0 +1,262 @@
|
|||||||
|
package com.bwssystems.util;
|
||||||
|
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.text.CharacterIterator;
|
||||||
|
import java.text.StringCharacterIterator;
|
||||||
|
|
||||||
|
public final class TextStringFormatter {
|
||||||
|
private TextStringFormatter() {
|
||||||
|
// empty - prevent construction
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Escapes characters for text appearing as data in the
|
||||||
|
<a href='http://www.json.org/'>Javascript Object Notation</a>
|
||||||
|
(JSON) data interchange format.
|
||||||
|
|
||||||
|
<P>The following commonly used control characters are escaped :
|
||||||
|
<table border='1' cellpadding='3' cellspacing='0'>
|
||||||
|
<tr><th> Character </th><th> Escaped As </th></tr>
|
||||||
|
<tr><td> " </td><td> \" </td></tr>
|
||||||
|
<tr><td> \ </td><td> \\ </td></tr>
|
||||||
|
<tr><td> / </td><td> \/ </td></tr>
|
||||||
|
<tr><td> back space </td><td> \b </td></tr>
|
||||||
|
<tr><td> form feed </td><td> \f </td></tr>
|
||||||
|
<tr><td> line feed </td><td> \n </td></tr>
|
||||||
|
<tr><td> carriage return </td><td> \r </td></tr>
|
||||||
|
<tr><td> tab </td><td> \t </td></tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<P>See <a href='http://www.ietf.org/rfc/rfc4627.txt'>RFC 4627</a> for more information.
|
||||||
|
*/
|
||||||
|
public static String forJSON(String aText) {
|
||||||
|
final StringBuilder result = new StringBuilder();
|
||||||
|
StringCharacterIterator iterator = new StringCharacterIterator(aText);
|
||||||
|
char character = iterator.current();
|
||||||
|
while (character != StringCharacterIterator.DONE) {
|
||||||
|
if (character == '\"') {
|
||||||
|
result.append("\\\"");
|
||||||
|
} else if (character == '\\') {
|
||||||
|
result.append("\\\\");
|
||||||
|
} else if (character == '/') {
|
||||||
|
result.append("\\/");
|
||||||
|
} else if (character == '\b') {
|
||||||
|
result.append("\\b");
|
||||||
|
} else if (character == '\f') {
|
||||||
|
result.append("\\f");
|
||||||
|
} else if (character == '\n') {
|
||||||
|
result.append("\\n");
|
||||||
|
} else if (character == '\r') {
|
||||||
|
result.append("\\r");
|
||||||
|
} else if (character == '\t') {
|
||||||
|
result.append("\\t");
|
||||||
|
} else {
|
||||||
|
// the char is not a special one
|
||||||
|
// add it to the result as is
|
||||||
|
result.append(character);
|
||||||
|
}
|
||||||
|
character = iterator.next();
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Escape characters for text appearing in HTML markup.
|
||||||
|
|
||||||
|
<P>This method exists as a defence against Cross Site Scripting (XSS) hacks.
|
||||||
|
The idea is to neutralize control characters commonly used by scripts, such that
|
||||||
|
they will not be executed by the browser. This is done by replacing the control
|
||||||
|
characters with their escaped equivalents.
|
||||||
|
See {@link hirondelle.web4j.security.SafeText} as well.
|
||||||
|
|
||||||
|
<P>The following characters are replaced with corresponding
|
||||||
|
HTML character entities :
|
||||||
|
<table border='1' cellpadding='3' cellspacing='0'>
|
||||||
|
<tr><th> Character </th><th>Replacement</th></tr>
|
||||||
|
<tr><td> < </td><td> < </td></tr>
|
||||||
|
<tr><td> > </td><td> > </td></tr>
|
||||||
|
<tr><td> & </td><td> & </td></tr>
|
||||||
|
<tr><td> " </td><td> "</td></tr>
|
||||||
|
<tr><td> \t </td><td> 	</td></tr>
|
||||||
|
<tr><td> ! </td><td> !</td></tr>
|
||||||
|
<tr><td> # </td><td> #</td></tr>
|
||||||
|
<tr><td> $ </td><td> $</td></tr>
|
||||||
|
<tr><td> % </td><td> %</td></tr>
|
||||||
|
<tr><td> ' </td><td> '</td></tr>
|
||||||
|
<tr><td> ( </td><td> (</td></tr>
|
||||||
|
<tr><td> ) </td><td> )</td></tr>
|
||||||
|
<tr><td> * </td><td> *</td></tr>
|
||||||
|
<tr><td> + </td><td> + </td></tr>
|
||||||
|
<tr><td> , </td><td> , </td></tr>
|
||||||
|
<tr><td> - </td><td> - </td></tr>
|
||||||
|
<tr><td> . </td><td> . </td></tr>
|
||||||
|
<tr><td> / </td><td> / </td></tr>
|
||||||
|
<tr><td> : </td><td> :</td></tr>
|
||||||
|
<tr><td> ; </td><td> ;</td></tr>
|
||||||
|
<tr><td> = </td><td> =</td></tr>
|
||||||
|
<tr><td> ? </td><td> ?</td></tr>
|
||||||
|
<tr><td> @ </td><td> @</td></tr>
|
||||||
|
<tr><td> [ </td><td> [</td></tr>
|
||||||
|
<tr><td> \ </td><td> \</td></tr>
|
||||||
|
<tr><td> ] </td><td> ]</td></tr>
|
||||||
|
<tr><td> ^ </td><td> ^</td></tr>
|
||||||
|
<tr><td> _ </td><td> _</td></tr>
|
||||||
|
<tr><td> ` </td><td> `</td></tr>
|
||||||
|
<tr><td> { </td><td> {</td></tr>
|
||||||
|
<tr><td> | </td><td> |</td></tr>
|
||||||
|
<tr><td> } </td><td> }</td></tr>
|
||||||
|
<tr><td> ~ </td><td> ~</td></tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<P>Note that JSTL's {@code <c:out>} escapes <em>only the first
|
||||||
|
five</em> of the above characters.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static String forHTML(String aText) {
|
||||||
|
final StringBuilder result = new StringBuilder();
|
||||||
|
final StringCharacterIterator iterator = new StringCharacterIterator(aText);
|
||||||
|
char character = iterator.current();
|
||||||
|
while (character != CharacterIterator.DONE) {
|
||||||
|
if (character == '<') {
|
||||||
|
result.append("<");
|
||||||
|
} else if (character == '>') {
|
||||||
|
result.append(">");
|
||||||
|
} else if (character == '&') {
|
||||||
|
result.append("&");
|
||||||
|
} else if (character == '\"') {
|
||||||
|
result.append(""");
|
||||||
|
} else if (character == '\t') {
|
||||||
|
addCharEntity(9, result);
|
||||||
|
} else if (character == '!') {
|
||||||
|
addCharEntity(33, result);
|
||||||
|
} else if (character == '#') {
|
||||||
|
addCharEntity(35, result);
|
||||||
|
} else if (character == '$') {
|
||||||
|
addCharEntity(36, result);
|
||||||
|
} else if (character == '%') {
|
||||||
|
addCharEntity(37, result);
|
||||||
|
} else if (character == '\'') {
|
||||||
|
addCharEntity(39, result);
|
||||||
|
} else if (character == '(') {
|
||||||
|
addCharEntity(40, result);
|
||||||
|
} else if (character == ')') {
|
||||||
|
addCharEntity(41, result);
|
||||||
|
} else if (character == '*') {
|
||||||
|
addCharEntity(42, result);
|
||||||
|
} else if (character == '+') {
|
||||||
|
addCharEntity(43, result);
|
||||||
|
} else if (character == ',') {
|
||||||
|
addCharEntity(44, result);
|
||||||
|
} else if (character == '-') {
|
||||||
|
addCharEntity(45, result);
|
||||||
|
} else if (character == '.') {
|
||||||
|
addCharEntity(46, result);
|
||||||
|
} else if (character == '/') {
|
||||||
|
addCharEntity(47, result);
|
||||||
|
} else if (character == ':') {
|
||||||
|
addCharEntity(58, result);
|
||||||
|
} else if (character == ';') {
|
||||||
|
addCharEntity(59, result);
|
||||||
|
} else if (character == '=') {
|
||||||
|
addCharEntity(61, result);
|
||||||
|
} else if (character == '?') {
|
||||||
|
addCharEntity(63, result);
|
||||||
|
} else if (character == '@') {
|
||||||
|
addCharEntity(64, result);
|
||||||
|
} else if (character == '[') {
|
||||||
|
addCharEntity(91, result);
|
||||||
|
} else if (character == '\\') {
|
||||||
|
addCharEntity(92, result);
|
||||||
|
} else if (character == ']') {
|
||||||
|
addCharEntity(93, result);
|
||||||
|
} else if (character == '^') {
|
||||||
|
addCharEntity(94, result);
|
||||||
|
} else if (character == '_') {
|
||||||
|
addCharEntity(95, result);
|
||||||
|
} else if (character == '`') {
|
||||||
|
addCharEntity(96, result);
|
||||||
|
} else if (character == '{') {
|
||||||
|
addCharEntity(123, result);
|
||||||
|
} else if (character == '|') {
|
||||||
|
addCharEntity(124, result);
|
||||||
|
} else if (character == '}') {
|
||||||
|
addCharEntity(125, result);
|
||||||
|
} else if (character == '~') {
|
||||||
|
addCharEntity(126, result);
|
||||||
|
} else {
|
||||||
|
// the char is not a special one
|
||||||
|
// add it to the result as is
|
||||||
|
result.append(character);
|
||||||
|
}
|
||||||
|
character = iterator.next();
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escape all ampersand characters in a URL.
|
||||||
|
*
|
||||||
|
* <P>
|
||||||
|
* Replaces all <tt>'&'</tt> characters with <tt>'&'</tt>.
|
||||||
|
*
|
||||||
|
* <P>
|
||||||
|
* An ampersand character may appear in the query string of a URL. The
|
||||||
|
* ampersand character is indeed valid in a URL.
|
||||||
|
* <em>However, URLs usually appear as an <tt>HREF</tt> attribute, and such
|
||||||
|
* attributes have the additional constraint that ampersands must be
|
||||||
|
* escaped.</em>
|
||||||
|
*
|
||||||
|
* <P>
|
||||||
|
* The JSTL <c:url> tag does indeed perform proper URL encoding of query
|
||||||
|
* parameters. But it does not, in general, produce text which is valid as
|
||||||
|
* an <tt>HREF</tt> attribute, simply because it does not escape the
|
||||||
|
* ampersand character. This is a nuisance when multiple query parameters
|
||||||
|
* appear in the URL, since it requires a little extra work.
|
||||||
|
*/
|
||||||
|
public static String forHrefAmpersand(String aURL) {
|
||||||
|
return aURL.replace("&", "&");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String forQuerySpace(String aURL) {
|
||||||
|
return aURL.replace(" ", "\u0020");
|
||||||
|
}
|
||||||
|
public static String forQuerySpaceUrl(String aURL) {
|
||||||
|
return aURL.replace(" ", "%20");
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Synonym for <tt>URLEncoder.encode(String, "UTF-8")</tt>.
|
||||||
|
*
|
||||||
|
* <P>
|
||||||
|
* Used to ensure that HTTP query strings are in proper form, by escaping
|
||||||
|
* special characters such as spaces.
|
||||||
|
*
|
||||||
|
* <P>
|
||||||
|
* It is important to note that if a query string appears in an
|
||||||
|
* <tt>HREF</tt> attribute, then there are two issues - ensuring the query
|
||||||
|
* string is valid HTTP (it is URL-encoded), and ensuring it is valid HTML
|
||||||
|
* (ensuring the ampersand is escaped).
|
||||||
|
*/
|
||||||
|
public static String forURL(String aURLFragment) {
|
||||||
|
String result = null;
|
||||||
|
try {
|
||||||
|
result = URLEncoder.encode(aURLFragment, "UTF-8");
|
||||||
|
} catch (UnsupportedEncodingException ex) {
|
||||||
|
throw new RuntimeException("UTF-8 not supported", ex);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void addCharEntity(Integer aIdx, StringBuilder aBuilder) {
|
||||||
|
String padding = "";
|
||||||
|
if (aIdx <= 9) {
|
||||||
|
padding = "00";
|
||||||
|
} else if (aIdx <= 99) {
|
||||||
|
padding = "0";
|
||||||
|
} else {
|
||||||
|
// no prefix
|
||||||
|
}
|
||||||
|
String number = padding + aIdx.toString();
|
||||||
|
aBuilder.append("&#" + number + ";");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,7 +26,7 @@ public class VeraHome {
|
|||||||
Iterator<NamedIP> theList = bridgeSettings.getVeraAddress().getDevices().iterator();
|
Iterator<NamedIP> theList = bridgeSettings.getVeraAddress().getDevices().iterator();
|
||||||
while(theList.hasNext()) {
|
while(theList.hasNext()) {
|
||||||
NamedIP aVera = theList.next();
|
NamedIP aVera = theList.next();
|
||||||
veras.put(aVera.getName(), new VeraInfo(aVera, bridgeSettings.isValidVera()));
|
veras.put(aVera.getName(), new VeraInfo(aVera));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,19 +28,15 @@ public class VeraInfo {
|
|||||||
private HttpClient httpClient;
|
private HttpClient httpClient;
|
||||||
private static final String SDATA_REQUEST = ":3480/data_request?id=sdata&output_format=json";
|
private static final String SDATA_REQUEST = ":3480/data_request?id=sdata&output_format=json";
|
||||||
private NamedIP veraAddress;
|
private NamedIP veraAddress;
|
||||||
private Boolean validVera;
|
|
||||||
|
|
||||||
public VeraInfo(NamedIP addressName, Boolean isValidVera) {
|
public VeraInfo(NamedIP addressName) {
|
||||||
super();
|
super();
|
||||||
httpClient = HttpClients.createDefault();
|
httpClient = HttpClients.createDefault();
|
||||||
veraAddress = addressName;
|
veraAddress = addressName;
|
||||||
validVera = isValidVera;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sdata getSdata() {
|
public Sdata getSdata() {
|
||||||
Sdata theSdata = null;
|
Sdata theSdata = null;
|
||||||
if(!validVera)
|
|
||||||
return theSdata;
|
|
||||||
|
|
||||||
String theUrl = "http://" + veraAddress.getIp() + SDATA_REQUEST;
|
String theUrl = "http://" + veraAddress.getIp() + SDATA_REQUEST;
|
||||||
String theData;
|
String theData;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
.scrollableContainer {
|
.scrollableContainer {
|
||||||
height: 800px;
|
max-height: 436px; /* sets max-height value for all standards-compliant browsers */
|
||||||
position: relative;
|
position: relative;
|
||||||
padding-top: 35px;
|
padding-top: 35px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@@ -28,7 +28,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.scrollArea {
|
.scrollArea {
|
||||||
height: 100%;
|
_height: expression( this.scrollHeight > 599 ? "600px" : "auto" ); /* sets max-height for IE6 */
|
||||||
|
max-height: 400px; /* sets max-height value for all standards-compliant browsers */
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
border: 1px solid #d5d5d5;
|
border: 1px solid #d5d5d5;
|
||||||
|
|||||||
@@ -31,6 +31,12 @@ app.config(function ($routeProvider) {
|
|||||||
}).when('/nest', {
|
}).when('/nest', {
|
||||||
templateUrl: 'views/nestactions.html',
|
templateUrl: 'views/nestactions.html',
|
||||||
controller: 'NestController'
|
controller: 'NestController'
|
||||||
|
}).when('/huedevices', {
|
||||||
|
templateUrl: 'views/huedevice.html',
|
||||||
|
controller: 'HueController'
|
||||||
|
}).when('/haldevices', {
|
||||||
|
templateUrl: 'views/haldevice.html',
|
||||||
|
controller: 'HalController'
|
||||||
}).otherwise({
|
}).otherwise({
|
||||||
templateUrl: 'views/configuration.html',
|
templateUrl: 'views/configuration.html',
|
||||||
controller: 'ViewingController'
|
controller: 'ViewingController'
|
||||||
@@ -42,14 +48,30 @@ app.run( function (bridgeService) {
|
|||||||
bridgeService.getHABridgeVersion();
|
bridgeService.getHABridgeVersion();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
String.prototype.replaceAll = function(search, replace)
|
||||||
|
{
|
||||||
|
//if replace is not sent, return original string otherwise it will
|
||||||
|
//replace search string with 'undefined'.
|
||||||
|
if (replace === undefined) {
|
||||||
|
return this.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.replace(new RegExp('[' + search + ']', 'g'), replace);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
app.service('bridgeService', function ($http, $window, ngToast) {
|
app.service('bridgeService', function ($http, $window, ngToast) {
|
||||||
var self = this;
|
var self = this;
|
||||||
this.state = {base: window.location.origin + "/api/devices", bridgelocation: window.location.origin, systemsbase: window.location.origin + "/system", huebase: window.location.origin + "/api", configs: [], backups: [], devices: [], device: [], type: "", settings: [], myToastMsg: [], logMsgs: [], loggerInfo: [], olddevicename: "", logShowAll: false, isInControl: false, showVera: false, showHarmony: false, showNest: false, habridgeversion: ""};
|
this.state = {base: window.location.origin + "/api/devices", bridgelocation: window.location.origin, systemsbase: window.location.origin + "/system", huebase: window.location.origin + "/api", configs: [], backups: [], devices: [], device: [], mapandid: [], type: "", settings: [], myToastMsg: [], logMsgs: [], loggerInfo: [], olddevicename: "", logShowAll: false, isInControl: false, showVera: false, showHarmony: false, showNest: false, showHue: false, showHal: false, habridgeversion: ""};
|
||||||
|
|
||||||
this.displayWarn = function(errorTitle, error) {
|
this.displayWarn = function(errorTitle, error) {
|
||||||
var toastContent = errorTitle;
|
var toastContent = errorTitle;
|
||||||
if(error != null && typeof(error) != 'undefined')
|
if(error != null && typeof(error) != 'undefined') {
|
||||||
toastContent = toastContent + " " + error.data.message + " with status: " + error.statusText + " - " + error.status;
|
if(error.data != null)
|
||||||
|
toastContent = toastContent + " " + error.data.message + " with status: " + error.statusText + " - " + error.status;
|
||||||
|
else
|
||||||
|
toastContent = error;
|
||||||
|
}
|
||||||
ngToast.create({
|
ngToast.create({
|
||||||
className: "warning",
|
className: "warning",
|
||||||
dismissButton: true,
|
dismissButton: true,
|
||||||
@@ -94,6 +116,8 @@ app.service('bridgeService', function ($http, $window, ngToast) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.clearDevice = function () {
|
this.clearDevice = function () {
|
||||||
|
if(self.state.device == null)
|
||||||
|
self.state.device = [];
|
||||||
self.state.device.id = "";
|
self.state.device.id = "";
|
||||||
self.state.device.mapType = null;
|
self.state.device.mapType = null;
|
||||||
self.state.device.mapId = null;
|
self.state.device.mapId = null;
|
||||||
@@ -103,6 +127,7 @@ app.service('bridgeService', function ($http, $window, ngToast) {
|
|||||||
self.state.device.deviceType = "custom";
|
self.state.device.deviceType = "custom";
|
||||||
self.state.device.targetDevice = null;
|
self.state.device.targetDevice = null;
|
||||||
self.state.device.offUrl = "";
|
self.state.device.offUrl = "";
|
||||||
|
self.state.device.headers = null;
|
||||||
self.state.device.httpVerb = null;
|
self.state.device.httpVerb = null;
|
||||||
self.state.device.contentType = null;
|
self.state.device.contentType = null;
|
||||||
self.state.device.contentBody = null;
|
self.state.device.contentBody = null;
|
||||||
@@ -140,6 +165,16 @@ app.service('bridgeService', function ($http, $window, ngToast) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.updateShowHue = function () {
|
||||||
|
this.state.showHue = self.state.settings.hueconfigured;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.updateShowHal = function () {
|
||||||
|
this.state.showHal = self.state.settings.halconfigured;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.loadBridgeSettings = function () {
|
this.loadBridgeSettings = function () {
|
||||||
return $http.get(this.state.systemsbase + "/settings").then(
|
return $http.get(this.state.systemsbase + "/settings").then(
|
||||||
function (response) {
|
function (response) {
|
||||||
@@ -147,6 +182,8 @@ app.service('bridgeService', function ($http, $window, ngToast) {
|
|||||||
self.updateShowVera();
|
self.updateShowVera();
|
||||||
self.updateShowHarmony();
|
self.updateShowHarmony();
|
||||||
self.updateShowNest();
|
self.updateShowNest();
|
||||||
|
self.updateShowHue();
|
||||||
|
self.updateShowHal();
|
||||||
},
|
},
|
||||||
function (error) {
|
function (error) {
|
||||||
self.displayWarn("Load Bridge Settings Error: ", error);
|
self.displayWarn("Load Bridge Settings Error: ", error);
|
||||||
@@ -211,6 +248,19 @@ app.service('bridgeService', function ($http, $window, ngToast) {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.viewHueDevices = function () {
|
||||||
|
if(!this.state.showHue)
|
||||||
|
return;
|
||||||
|
return $http.get(this.state.base + "/hue/devices").then(
|
||||||
|
function (response) {
|
||||||
|
self.state.huedevices = response.data;
|
||||||
|
},
|
||||||
|
function (error) {
|
||||||
|
self.displayWarn("Get Hue Items Error: ", error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
this.viewVeraDevices = function () {
|
this.viewVeraDevices = function () {
|
||||||
if(!this.state.showVera)
|
if(!this.state.showVera)
|
||||||
return;
|
return;
|
||||||
@@ -263,6 +313,19 @@ app.service('bridgeService', function ($http, $window, ngToast) {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.viewHalDevices = function () {
|
||||||
|
if(!this.state.showHal)
|
||||||
|
return;
|
||||||
|
return $http.get(this.state.base + "/hal/devices").then(
|
||||||
|
function (response) {
|
||||||
|
self.state.haldevices = response.data;
|
||||||
|
},
|
||||||
|
function (error) {
|
||||||
|
self.displayWarn("Get Hal Devices Error: ", error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
this.updateLogLevels = function(logComponents) {
|
this.updateLogLevels = function(logComponents) {
|
||||||
return $http.put(this.state.systemsbase + "/logmgmt/update", logComponents ).then(
|
return $http.put(this.state.systemsbase + "/logmgmt/update", logComponents ).then(
|
||||||
function (response) {
|
function (response) {
|
||||||
@@ -295,6 +358,7 @@ app.service('bridgeService', function ($http, $window, ngToast) {
|
|||||||
this.bulkAddDevice = function (devices) {
|
this.bulkAddDevice = function (devices) {
|
||||||
return $http.post(this.state.base, devices).then(
|
return $http.post(this.state.base, devices).then(
|
||||||
function (response) {
|
function (response) {
|
||||||
|
self.displaySuccess("Bulk device add successful.");
|
||||||
},
|
},
|
||||||
function (error) {
|
function (error) {
|
||||||
self.displayWarn("Bulk Add new Device Error: ", error);
|
self.displayWarn("Bulk Add new Device Error: ", error);
|
||||||
@@ -535,7 +599,7 @@ app.controller('SystemController', function ($scope, $location, $http, $window,
|
|||||||
bridgeService.viewConfigs();
|
bridgeService.viewConfigs();
|
||||||
$scope.bridge = bridgeService.state;
|
$scope.bridge = bridgeService.state;
|
||||||
$scope.optionalbackupname = "";
|
$scope.optionalbackupname = "";
|
||||||
$scope.isInControl = false;
|
$scope.bridge.isInControl = false;
|
||||||
$scope.visible = false;
|
$scope.visible = false;
|
||||||
$scope.imgUrl = "glyphicon glyphicon-plus";
|
$scope.imgUrl = "glyphicon glyphicon-plus";
|
||||||
$scope.addVeratoSettings = function (newveraname, newveraip) {
|
$scope.addVeratoSettings = function (newveraname, newveraip) {
|
||||||
@@ -570,21 +634,47 @@ app.controller('SystemController', function ($scope, $location, $http, $window,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
$scope.addHuetoSettings = function (newhuename, newhueip) {
|
||||||
|
if($scope.bridge.settings.hueaddress == null) {
|
||||||
|
$scope.bridge.settings.hueaddress = { devices: [] };
|
||||||
|
}
|
||||||
|
var newhue = {name: newhuename, ip: newhueip }
|
||||||
|
$scope.bridge.settings.hueaddress.devices.push(newhue);
|
||||||
|
$scope.newhuename = null;
|
||||||
|
$scope.newhueip = null;
|
||||||
|
};
|
||||||
|
$scope.removeHuetoSettings = function (huename, hueip) {
|
||||||
|
for(var i = $scope.bridge.settings.hueaddress.devices.length - 1; i >= 0; i--) {
|
||||||
|
if($scope.bridge.settings.hueaddress.devices[i].name === huename && $scope.bridge.settings.hueaddress.devices[i].ip === hueip) {
|
||||||
|
$scope.bridge.settings.hueaddress.devices.splice(i, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
$scope.addHaltoSettings = function (newhalname, newhalip) {
|
||||||
|
if($scope.bridge.settings.haladdress == null) {
|
||||||
|
$scope.bridge.settings.haladdress = { devices: [] };
|
||||||
|
}
|
||||||
|
var newhal = {name: newhalname, ip: newhalip }
|
||||||
|
$scope.bridge.settings.haladdress.devices.push(newhal);
|
||||||
|
$scope.newhalname = null;
|
||||||
|
$scope.newhalip = null;
|
||||||
|
};
|
||||||
|
$scope.removeHaltoSettings = function (halname, halip) {
|
||||||
|
for(var i = $scope.bridge.settings.haladdress.devices.length - 1; i >= 0; i--) {
|
||||||
|
if($scope.bridge.settings.haladdress.devices[i].name === halname && $scope.bridge.settings.haladdress.devices[i].ip === halip) {
|
||||||
|
$scope.bridge.settings.haladdress.devices.splice(i, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
$scope.bridgeReinit = function () {
|
$scope.bridgeReinit = function () {
|
||||||
$scope.isInControl = false;
|
|
||||||
bridgeService.reinit();
|
bridgeService.reinit();
|
||||||
};
|
};
|
||||||
$scope.bridgeStop = function () {
|
$scope.bridgeStop = function () {
|
||||||
$scope.isInControl = false;
|
|
||||||
bridgeService.stop();
|
bridgeService.stop();
|
||||||
};
|
};
|
||||||
$scope.saveSettings = function() {
|
$scope.saveSettings = function() {
|
||||||
bridgeService.saveSettings();
|
bridgeService.saveSettings();
|
||||||
};
|
};
|
||||||
$scope.setBridgeUrl = function (url) {
|
|
||||||
bridgeService.state.base = url;
|
|
||||||
bridgeService.viewDevices();
|
|
||||||
};
|
|
||||||
$scope.goBridgeUrl = function (url) {
|
$scope.goBridgeUrl = function (url) {
|
||||||
window.open(url, "_blank");
|
window.open(url, "_blank");
|
||||||
};
|
};
|
||||||
@@ -662,13 +752,15 @@ app.controller('ViewingController', function ($scope, $location, $http, $window,
|
|||||||
var dialogNeeded = false;
|
var dialogNeeded = false;
|
||||||
if((type == "on" && (bridgeService.aContainsB(device.onUrl, "${intensity.byte}") ||
|
if((type == "on" && (bridgeService.aContainsB(device.onUrl, "${intensity.byte}") ||
|
||||||
bridgeService.aContainsB(device.onUrl, "${intensity.percent}") ||
|
bridgeService.aContainsB(device.onUrl, "${intensity.percent}") ||
|
||||||
bridgeService.aContainsB(device.onUrl, "${intensity.math("))) ||
|
bridgeService.aContainsB(device.onUrl, "${intensity.math(")) ||
|
||||||
(type == "off" && (bridgeService.aContainsB(device.offUrl, "${intensity.byte}") ||
|
(type == "off" && (bridgeService.aContainsB(device.offUrl, "${intensity.byte}") ||
|
||||||
bridgeService.aContainsB(device.offUrl, "${intensity.percent}") ||
|
bridgeService.aContainsB(device.offUrl, "${intensity.percent}") ||
|
||||||
bridgeService.aContainsB(device.offUrl, "${intensity.math("))) ||
|
bridgeService.aContainsB(device.offUrl, "${intensity.math("))) ||
|
||||||
(type == "dim" && (bridgeService.aContainsB(device.dimUrl, "${intensity.byte}") ||
|
(type == "dim" && (bridgeService.aContainsB(device.dimUrl, "${intensity.byte}") ||
|
||||||
bridgeService.aContainsB(device.dimUrl, "${intensity.percent}") ||
|
bridgeService.aContainsB(device.dimUrl, "${intensity.percent}") ||
|
||||||
bridgeService.aContainsB(device.dimUrl, "${intensity.math(")))) {
|
bridgeService.aContainsB(device.dimUrl, "${intensity.math(") ||
|
||||||
|
bridgeService.aContainsB(device.deviceType, "passthru") ||
|
||||||
|
bridgeService.aContainsB(device.mapType, "hueDevice"))))) {
|
||||||
$scope.bridge.device = device;
|
$scope.bridge.device = device;
|
||||||
$scope.bridge.type = type;
|
$scope.bridge.type = type;
|
||||||
ngDialog.open({
|
ngDialog.open({
|
||||||
@@ -681,7 +773,12 @@ app.controller('ViewingController', function ($scope, $location, $http, $window,
|
|||||||
bridgeService.testUrl(device, type);
|
bridgeService.testUrl(device, type);
|
||||||
};
|
};
|
||||||
$scope.deleteDevice = function (device) {
|
$scope.deleteDevice = function (device) {
|
||||||
bridgeService.deleteDevice(device.id);
|
$scope.bridge.device = device;
|
||||||
|
ngDialog.open({
|
||||||
|
template: 'deleteDialog',
|
||||||
|
controller: 'DeleteDialogCtrl',
|
||||||
|
className: 'ngdialog-theme-default'
|
||||||
|
});
|
||||||
};
|
};
|
||||||
$scope.editDevice = function (device) {
|
$scope.editDevice = function (device) {
|
||||||
bridgeService.editDevice(device);
|
bridgeService.editDevice(device);
|
||||||
@@ -746,11 +843,49 @@ app.controller('ValueDialogCtrl', function ($scope, bridgeService, ngDialog) {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
app.controller('VeraController', function ($scope, $location, $http, bridgeService) {
|
app.controller('DeleteDialogCtrl', function ($scope, bridgeService, ngDialog) {
|
||||||
|
$scope.bridge = bridgeService.state;
|
||||||
|
$scope.device = $scope.bridge.device;
|
||||||
|
$scope.deleteDevice = function (device) {
|
||||||
|
ngDialog.close('ngdialog1');
|
||||||
|
bridgeService.deleteDevice(device.id);
|
||||||
|
bridgeService.viewDevices();
|
||||||
|
$scope.bridge.device = null;
|
||||||
|
$scope.bridge.type = "";
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
app.controller('DeleteMapandIdDialogCtrl', function ($scope, bridgeService, ngDialog) {
|
||||||
|
$scope.bridge = bridgeService.state;
|
||||||
|
$scope.mapandid = $scope.bridge.mapandid;
|
||||||
|
$scope.deleteMapandId = function (mapandid) {
|
||||||
|
ngDialog.close('ngdialog1');
|
||||||
|
bridgeService.deleteDeviceByMapId(mapandid.id, mapandid.mapType);
|
||||||
|
bridgeService.viewDevices();
|
||||||
|
if(mapandid.mapType == "veraDevice")
|
||||||
|
bridgeService.viewVeraDevices();
|
||||||
|
if(mapandid.mapType == "veraScene")
|
||||||
|
bridgeService.viewVeraScenes();
|
||||||
|
if(mapandid.mapType == "harmonyActivity")
|
||||||
|
bridgeService.viewHarmonyActivities();
|
||||||
|
if(mapandid.mapType == "harmonyButton")
|
||||||
|
bridgeService.viewHarmonyDevices();
|
||||||
|
if(mapandid.mapType == "nestThermoSet" || mapandid.mapType == "nestHomeAway")
|
||||||
|
bridgeService.viewNestItems();
|
||||||
|
if(mapandid.mapType == "hueDevice")
|
||||||
|
bridgeService.viewHueDevices();
|
||||||
|
if(mapandid.mapType == "halDevice")
|
||||||
|
bridgeService.viewHalDevices();
|
||||||
|
$scope.bridge.mapandid = null;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
app.controller('VeraController', function ($scope, $location, $http, bridgeService, ngDialog) {
|
||||||
$scope.bridge = bridgeService.state;
|
$scope.bridge = bridgeService.state;
|
||||||
$scope.device = $scope.bridge.device;
|
$scope.device = $scope.bridge.device;
|
||||||
$scope.device_dim_control = "";
|
$scope.device_dim_control = "";
|
||||||
$scope.bulk = { devices: [] };
|
$scope.bulk = { devices: [] };
|
||||||
|
$scope.selectAll = false;
|
||||||
var veraList = angular.fromJson($scope.bridge.settings.veraaddress);
|
var veraList = angular.fromJson($scope.bridge.settings.veraaddress);
|
||||||
if(veraList != null)
|
if(veraList != null)
|
||||||
$scope.vera = {base: "http://" + veraList.devices[0].ip, port: "3480", id: ""};
|
$scope.vera = {base: "http://" + veraList.devices[0].ip, port: "3480", id: ""};
|
||||||
@@ -835,7 +970,9 @@ app.controller('VeraController', function ($scope, $location, $http, bridgeServi
|
|||||||
deviceType: $scope.device.deviceType,
|
deviceType: $scope.device.deviceType,
|
||||||
targetDevice: $scope.device.targetDevice,
|
targetDevice: $scope.device.targetDevice,
|
||||||
onUrl: $scope.device.onUrl,
|
onUrl: $scope.device.onUrl,
|
||||||
|
dimUrl: $scope.device.dimUrl,
|
||||||
offUrl: $scope.device.offUrl,
|
offUrl: $scope.device.offUrl,
|
||||||
|
headers: $scope.device.headers,
|
||||||
httpVerb: $scope.device.httpVerb,
|
httpVerb: $scope.device.httpVerb,
|
||||||
contentType: $scope.device.contentType,
|
contentType: $scope.device.contentType,
|
||||||
contentBody: $scope.device.contentBody,
|
contentBody: $scope.device.contentBody,
|
||||||
@@ -844,12 +981,19 @@ app.controller('VeraController', function ($scope, $location, $http, bridgeServi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bridgeService.bulkAddDevice(devicesList);
|
bridgeService.bulkAddDevice(devicesList).then(
|
||||||
$scope.clearDevice();
|
function () {
|
||||||
bridgeService.viewDevices();
|
$scope.clearDevice();
|
||||||
bridgeService.viewVeraDevices();
|
bridgeService.viewDevices();
|
||||||
bridgeService.viewVeraScenes();
|
bridgeService.viewVeraDevices();
|
||||||
|
bridgeService.viewVeraScenes();
|
||||||
|
},
|
||||||
|
function (error) {
|
||||||
|
bridgeService.displayWarn("Error adding Vera devices in bulk.", error)
|
||||||
|
}
|
||||||
|
);
|
||||||
$scope.bulk = { devices: [] };
|
$scope.bulk = { devices: [] };
|
||||||
|
$scope.selectAll = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.toggleSelection = function toggleSelection(deviceId) {
|
$scope.toggleSelection = function toggleSelection(deviceId) {
|
||||||
@@ -858,11 +1002,28 @@ app.controller('VeraController', function ($scope, $location, $http, bridgeServi
|
|||||||
// is currently selected
|
// is currently selected
|
||||||
if (idx > -1) {
|
if (idx > -1) {
|
||||||
$scope.bulk.devices.splice(idx, 1);
|
$scope.bulk.devices.splice(idx, 1);
|
||||||
|
if($scope.bulk.devices.length == 0 && $scope.selectAll)
|
||||||
|
$scope.selectAll = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// is newly selected
|
// is newly selected
|
||||||
else {
|
else {
|
||||||
$scope.bulk.devices.push(deviceId);
|
$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.veradevices.length; x++) {
|
||||||
|
if($scope.bulk.devices.indexOf(bridgeService.state.veradevices[x]) < 0 && !bridgeService.findDeviceByMapId(bridgeService.state.veradevices[x].id, bridgeService.state.veradevices[x].veraname, "veraDevice"))
|
||||||
|
$scope.bulk.devices.push(bridgeService.state.veradevices[x].id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -875,15 +1036,17 @@ app.controller('VeraController', function ($scope, $location, $http, bridgeServi
|
|||||||
};
|
};
|
||||||
|
|
||||||
$scope.deleteDeviceByMapId = function (id, mapType) {
|
$scope.deleteDeviceByMapId = function (id, mapType) {
|
||||||
bridgeService.deleteDeviceByMapId(id, mapType);
|
$scope.bridge.mapandid = { id, mapType };
|
||||||
bridgeService.viewDevices();
|
ngDialog.open({
|
||||||
bridgeService.viewVeraDevices();
|
template: 'deleteMapandIdDialog',
|
||||||
bridgeService.viewVeraScenes();
|
controller: 'DeleteMapandIdDialogCtrl',
|
||||||
|
className: 'ngdialog-theme-default'
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
app.controller('HarmonyController', function ($scope, $location, $http, bridgeService) {
|
app.controller('HarmonyController', function ($scope, $location, $http, bridgeService, ngDialog) {
|
||||||
$scope.bridge = bridgeService.state;
|
$scope.bridge = bridgeService.state;
|
||||||
$scope.device = $scope.bridge.device;
|
$scope.device = $scope.bridge.device;
|
||||||
bridgeService.viewHarmonyActivities();
|
bridgeService.viewHarmonyActivities();
|
||||||
@@ -907,21 +1070,22 @@ app.controller('HarmonyController', function ($scope, $location, $http, bridgeSe
|
|||||||
};
|
};
|
||||||
|
|
||||||
$scope.buildButtonUrls = function (harmonydevice, onbutton, offbutton) {
|
$scope.buildButtonUrls = function (harmonydevice, onbutton, offbutton) {
|
||||||
bridgeService.clearDevice();
|
|
||||||
var currentOn = $scope.device.onUrl;
|
var currentOn = $scope.device.onUrl;
|
||||||
var currentOff = $scope.device.offUrl;
|
var currentOff = $scope.device.offUrl;
|
||||||
var actionOn = angular.fromJson(onbutton);
|
var actionOn = angular.fromJson(onbutton);
|
||||||
var actionOff = angular.fromJson(offbutton);
|
var actionOff = angular.fromJson(offbutton);
|
||||||
if( $scope.device.mapType == "harmonyButton") {
|
if( $scope.device.mapType == "harmonyButton") {
|
||||||
|
$scope.device.mapId = $scope.device.mapId + "-" + actionOn.command;
|
||||||
$scope.device.onUrl = currentOn.substr(0, currentOn.indexOf("]")) + ",{\"device\":\"" + harmonydevice.device.id + "\",\"button\":\"" + actionOn.command + "\"}]";
|
$scope.device.onUrl = currentOn.substr(0, currentOn.indexOf("]")) + ",{\"device\":\"" + harmonydevice.device.id + "\",\"button\":\"" + actionOn.command + "\"}]";
|
||||||
$scope.device.offUrl = currentOff.substr(0, currentOff.indexOf("]")) + ",{\"device\":\"" + harmonydevice.device.id + "\",\"button\":\"" + actionOff.command + "\"}]";
|
$scope.device.offUrl = currentOff.substr(0, currentOff.indexOf("]")) + ",{\"device\":\"" + harmonydevice.device.id + "\",\"button\":\"" + actionOff.command + "\"}]";
|
||||||
}
|
}
|
||||||
else if ($scope.device.mapType == null || $scope.device.mapType == "") {
|
else if ($scope.device.mapType == null || $scope.device.mapType == "") {
|
||||||
|
bridgeService.clearDevice();
|
||||||
$scope.device.deviceType = "button";
|
$scope.device.deviceType = "button";
|
||||||
$scope.device.targetDevice = harmonydevice.hub;
|
$scope.device.targetDevice = harmonydevice.hub;
|
||||||
$scope.device.name = harmonydevice.device.label;
|
$scope.device.name = harmonydevice.device.label;
|
||||||
$scope.device.mapType = "harmonyButton";
|
$scope.device.mapType = "harmonyButton";
|
||||||
$scope.device.mapId = harmonydevice.device.id + "-" + actionOn.command + "-" + actionOff.command;
|
$scope.device.mapId = harmonydevice.device.id + "-" + actionOn.command;
|
||||||
$scope.device.onUrl = "[{\"device\":\"" + harmonydevice.device.id + "\",\"button\":\"" + actionOn.command + "\"}]";
|
$scope.device.onUrl = "[{\"device\":\"" + harmonydevice.device.id + "\",\"button\":\"" + actionOn.command + "\"}]";
|
||||||
$scope.device.offUrl = "[{\"device\":\"" + harmonydevice.device.id + "\",\"button\":\"" + actionOff.command + "\"}]";
|
$scope.device.offUrl = "[{\"device\":\"" + harmonydevice.device.id + "\",\"button\":\"" + actionOff.command + "\"}]";
|
||||||
}
|
}
|
||||||
@@ -952,15 +1116,17 @@ app.controller('HarmonyController', function ($scope, $location, $http, bridgeSe
|
|||||||
};
|
};
|
||||||
|
|
||||||
$scope.deleteDeviceByMapId = function (id, mapType) {
|
$scope.deleteDeviceByMapId = function (id, mapType) {
|
||||||
bridgeService.deleteDeviceByMapId(id, mapType);
|
$scope.bridge.mapandid = { id, mapType };
|
||||||
bridgeService.viewDevices();
|
ngDialog.open({
|
||||||
bridgeService.viewHarmonyActivities();
|
template: 'deleteMapandIdDialog',
|
||||||
bridgeService.viewHarmonyDevices();
|
controller: 'DeleteMapandIdDialogCtrl',
|
||||||
|
className: 'ngdialog-theme-default'
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
app.controller('NestController', function ($scope, $location, $http, bridgeService) {
|
app.controller('NestController', function ($scope, $location, $http, bridgeService, ngDialog) {
|
||||||
$scope.bridge = bridgeService.state;
|
$scope.bridge = bridgeService.state;
|
||||||
$scope.device = $scope.bridge.device;
|
$scope.device = $scope.bridge.device;
|
||||||
bridgeService.viewNestItems();
|
bridgeService.viewNestItems();
|
||||||
@@ -1072,9 +1238,460 @@ app.controller('NestController', function ($scope, $location, $http, bridgeServi
|
|||||||
};
|
};
|
||||||
|
|
||||||
$scope.deleteDeviceByMapId = function (id, mapType) {
|
$scope.deleteDeviceByMapId = function (id, mapType) {
|
||||||
bridgeService.deleteDeviceByMapId(id, mapType);
|
$scope.bridge.mapandid = { id, mapType };
|
||||||
bridgeService.viewDevices();
|
ngDialog.open({
|
||||||
bridgeService.viewNestItems();
|
template: 'deleteMapandIdDialog',
|
||||||
|
controller: 'DeleteMapandIdDialogCtrl',
|
||||||
|
className: 'ngdialog-theme-default'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
app.controller('HueController', function ($scope, $location, $http, bridgeService, ngDialog) {
|
||||||
|
$scope.bridge = bridgeService.state;
|
||||||
|
$scope.device = $scope.bridge.device;
|
||||||
|
$scope.bulk = { devices: [] };
|
||||||
|
$scope.selectAll = false;
|
||||||
|
bridgeService.viewHueDevices();
|
||||||
|
$scope.imgButtonsUrl = "glyphicon glyphicon-plus";
|
||||||
|
$scope.buttonsVisible = false;
|
||||||
|
|
||||||
|
$scope.clearDevice = function () {
|
||||||
|
bridgeService.clearDevice();
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.buildDeviceUrls = function (huedevice) {
|
||||||
|
bridgeService.clearDevice();
|
||||||
|
if($scope.device == null)
|
||||||
|
$scope.device = $scope.bridge.device;
|
||||||
|
$scope.device.deviceType = "passthru";
|
||||||
|
$scope.device.name = huedevice.device.name;
|
||||||
|
$scope.device.targetDevice = huedevice.huename;
|
||||||
|
$scope.device.contentType = "application/json";
|
||||||
|
$scope.device.mapType = "hueDevice";
|
||||||
|
$scope.device.mapId = huedevice.device.uniqueid;
|
||||||
|
$scope.device.onUrl = "{\"ipAddress\":\"" + huedevice.hueaddress + "\",\"deviceId\":\"" + huedevice.huedeviceid +"\"}";
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.addDevice = function () {
|
||||||
|
if($scope.device.name == "" && $scope.device.onUrl == "")
|
||||||
|
return;
|
||||||
|
bridgeService.addDevice($scope.device).then(
|
||||||
|
function () {
|
||||||
|
$scope.clearDevice();
|
||||||
|
bridgeService.viewDevices();
|
||||||
|
bridgeService.viewHueDevices();
|
||||||
|
},
|
||||||
|
function (error) {
|
||||||
|
bridgeService.displayWarn("Error adding device: " + $scope.device.name, error)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.bulkAddDevices = function() {
|
||||||
|
var devicesList = [];
|
||||||
|
for(var i = 0; i < $scope.bulk.devices.length; i++) {
|
||||||
|
for(var x = 0; x < bridgeService.state.huedevices.length; x++) {
|
||||||
|
if(bridgeService.state.huedevices[x].device.uniqueid == $scope.bulk.devices[i]) {
|
||||||
|
$scope.buildDeviceUrls(bridgeService.state.huedevices[x]);
|
||||||
|
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,
|
||||||
|
contentBodyOff: $scope.device.contentBodyOff
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bridgeService.bulkAddDevice(devicesList).then(
|
||||||
|
function () {
|
||||||
|
$scope.clearDevice();
|
||||||
|
bridgeService.viewDevices();
|
||||||
|
bridgeService.viewHueDevices();
|
||||||
|
},
|
||||||
|
function (error) {
|
||||||
|
bridgeService.displayWarn("Error adding Hue 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.huedevices.length; x++) {
|
||||||
|
if($scope.bulk.devices.indexOf(bridgeService.state.huedevices[x]) < 0 && !bridgeService.findDeviceByMapId(bridgeService.state.huedevices[x].device.uniqueid, bridgeService.state.huedevices[x].huename, "hueDevice"))
|
||||||
|
$scope.bulk.devices.push(bridgeService.state.huedevices[x].device.uniqueid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.toggleButtons = function () {
|
||||||
|
$scope.buttonsVisible = !$scope.buttonsVisible;
|
||||||
|
if($scope.buttonsVisible)
|
||||||
|
$scope.imgButtonsUrl = "glyphicon glyphicon-minus";
|
||||||
|
else
|
||||||
|
$scope.imgButtonsUrl = "glyphicon glyphicon-plus";
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.deleteDeviceByMapId = function (id, mapType) {
|
||||||
|
$scope.bridge.mapandid = { id, mapType };
|
||||||
|
ngDialog.open({
|
||||||
|
template: 'deleteMapandIdDialog',
|
||||||
|
controller: 'DeleteMapandIdDialogCtrl',
|
||||||
|
className: 'ngdialog-theme-default'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
app.controller('HalController', function ($scope, $location, $http, bridgeService, ngDialog) {
|
||||||
|
$scope.bridge = bridgeService.state;
|
||||||
|
$scope.device = $scope.bridge.device;
|
||||||
|
$scope.device_dim_control = "";
|
||||||
|
$scope.bulk = { devices: [] };
|
||||||
|
$scope.selectAll = false;
|
||||||
|
bridgeService.viewHalDevices();
|
||||||
|
$scope.imgButtonsUrl = "glyphicon glyphicon-plus";
|
||||||
|
$scope.buttonsVisible = false;
|
||||||
|
|
||||||
|
$scope.clearDevice = function () {
|
||||||
|
bridgeService.clearDevice();
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.buildDeviceUrls = function (haldevice, dim_control) {
|
||||||
|
bridgeService.clearDevice();
|
||||||
|
$scope.device = $scope.bridge.device;
|
||||||
|
var preOnCmd = "";
|
||||||
|
var preDimCmd = "";
|
||||||
|
var preOffCmd = "";
|
||||||
|
var nameCmd = ""
|
||||||
|
var postCmd = "?Token=" + $scope.bridge.settings.haltoken;
|
||||||
|
if(haldevice.haldevicetype == "Group") {
|
||||||
|
$scope.device.deviceType = "group";
|
||||||
|
preOnCmd = "/GroupService!GroupCmd=On";
|
||||||
|
preOffCmd = "/GroupService!GroupCmd=Off";
|
||||||
|
nameCmd = "!GroupName=";
|
||||||
|
}
|
||||||
|
else if(haldevice.haldevicetype == "Macro") {
|
||||||
|
$scope.device.deviceType = "macro";
|
||||||
|
preOnCmd = "/MacroService!MacroCmd=Set!MacroName=";
|
||||||
|
preOffCmd = preOnCmd;
|
||||||
|
}
|
||||||
|
else if(haldevice.haldevicetype == "Scene") {
|
||||||
|
$scope.device.deviceType = "scene";
|
||||||
|
preOnCmd = "/SceneService!SceneCmd=Set!SceneName=";
|
||||||
|
preOffCmd = preOnCmd;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$scope.device.deviceType = "switch";
|
||||||
|
preOnCmd = "/DeviceService!DeviceCmd=SetDevice!DeviceValue=On";
|
||||||
|
preDimCmd = "/DeviceService!DeviceCmd=SetDevice!DeviceValue=Dim!DevicePercent=";
|
||||||
|
preOffCmd = "/DeviceService!DeviceCmd=SetDevice!DeviceValue=Off";
|
||||||
|
nameCmd = "!DeviceName=";
|
||||||
|
}
|
||||||
|
$scope.device.name = haldevice.haldevicename;
|
||||||
|
$scope.device.targetDevice = haldevice.halname;
|
||||||
|
$scope.device.mapType = "halDevice";
|
||||||
|
$scope.device.mapId = haldevice.haldevicename + "-" + haldevice.halname;
|
||||||
|
if((dim_control.indexOf("byte") >= 0 || dim_control.indexOf("percent") >= 0 || dim_control.indexOf("math") >= 0) && $scope.device.deviceType == "switch")
|
||||||
|
$scope.device.dimUrl = "http://" + haldevice.haladdress
|
||||||
|
+ preDimCmd
|
||||||
|
+ dim_control
|
||||||
|
+ nameCmd
|
||||||
|
+ haldevice.haldevicename.replaceAll(" ", "%20")
|
||||||
|
+ postCmd;
|
||||||
|
else
|
||||||
|
$scope.device.dimUrl = "http://" + haldevice.haladdress
|
||||||
|
+ preOnCmd
|
||||||
|
+ nameCmd
|
||||||
|
+ haldevice.haldevicename.replaceAll(" ", "%20")
|
||||||
|
+ postCmd;
|
||||||
|
$scope.device.onUrl = "http://" + haldevice.haladdress
|
||||||
|
+ preOnCmd
|
||||||
|
+ nameCmd
|
||||||
|
+ haldevice.haldevicename.replaceAll(" ", "%20")
|
||||||
|
+ postCmd;
|
||||||
|
$scope.device.offUrl = "http://" + haldevice.haladdress
|
||||||
|
+ preOffCmd
|
||||||
|
+ nameCmd
|
||||||
|
+ haldevice.haldevicename.replaceAll(" ", "%20")
|
||||||
|
+ postCmd;
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.buildButtonUrls = function (haldevice, onbutton, offbutton) {
|
||||||
|
var currentOn = $scope.device.onUrl;
|
||||||
|
var currentOff = $scope.device.offUrl;
|
||||||
|
var actionOn = angular.fromJson(onbutton);
|
||||||
|
var actionOff = angular.fromJson(offbutton);
|
||||||
|
if( $scope.device.mapType == "halButton") {
|
||||||
|
$scope.device.mapId = $scope.device.mapId + "-" + actionOn.DeviceName;
|
||||||
|
$scope.device.onUrl = currentOn.substr(0, currentOn.indexOf("]")) + ",{\"item\":\"http://" + haldevice.haladdress + "/IrService!IrCmd=Set!IrDevice=" + haldevice.haldevicename.replaceAll(" ", "%20") + "!IrButton=" + actionOn.DeviceName.replaceAll(" ", "%20") + "?Token=" + $scope.bridge.settings.haltoken +"\"}]";
|
||||||
|
$scope.device.offUrl = currentOff.substr(0, currentOff.indexOf("]")) + ",{\"item\":\"http://" + haldevice.haladdress + "/IrService!IrCmd=Set!IrDevice=" + haldevice.haldevicename.replaceAll(" ", "%20") + "!IrButton=" + actionOff.DeviceName.replaceAll(" ", "%20") + "?Token=" + $scope.bridge.settings.haltoken + "\"}]";
|
||||||
|
}
|
||||||
|
else if ($scope.device.mapType == null || $scope.device.mapType == "") {
|
||||||
|
bridgeService.clearDevice();
|
||||||
|
$scope.device.deviceType = "button";
|
||||||
|
$scope.device.targetDevice = haldevice.halname;
|
||||||
|
$scope.device.name = haldevice.haldevicename;
|
||||||
|
$scope.device.mapType = "halButton";
|
||||||
|
$scope.device.mapId = haldevice.haldevicename + "-" + haldevice.halname + "-" + actionOn.DeviceName;
|
||||||
|
$scope.device.onUrl = "[{\"item\":\"http://" + haldevice.haladdress + "/IrService!IrCmd=Set!IrDevice=" + haldevice.haldevicename.replaceAll(" ", "%20") + "!IrButton=" + actionOn.DeviceName.replaceAll(" ", "%20") + "?Token=" + $scope.bridge.settings.haltoken + "\"}]";
|
||||||
|
$scope.device.offUrl = "[{\"item\":\"http://" + haldevice.haladdress + "/IrService!IrCmd=Set!IrDevice=" + haldevice.haldevicename.replaceAll(" ", "%20") + "!IrButton=" + actionOff.DeviceName.replaceAll(" ", "%20") + "?Token=" + $scope.bridge.settings.haltoken + "\"}]";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.buildHALHomeUrls = function (haldevice) {
|
||||||
|
bridgeService.clearDevice();
|
||||||
|
$scope.device.deviceType = "home";
|
||||||
|
$scope.device.name = haldevice.haldevicename;
|
||||||
|
$scope.device.targetDevice = haldevice.halname;
|
||||||
|
$scope.device.mapType = "halHome";
|
||||||
|
$scope.device.mapId = haldevice.haldevicename + "-" + haldevice.halname + "-HomeAway";
|
||||||
|
$scope.device.onUrl = "http://" + haldevice.haladdress + "/ModeService!ModeCmd=Set!ModeName=Home?Token=" + $scope.bridge.settings.haltoken;
|
||||||
|
$scope.device.offUrl = "http://" + haldevice.haladdress + "/ModeService!ModeCmd=Set!ModeName=Away?Token=" + $scope.bridge.settings.haltoken;
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.buildHALHeatUrls = function (haldevice) {
|
||||||
|
bridgeService.clearDevice();
|
||||||
|
$scope.device.deviceType = "thermo";
|
||||||
|
$scope.device.name = haldevice.haldevicename + " Heat";
|
||||||
|
$scope.device.targetDevice = haldevice.halname;
|
||||||
|
$scope.device.mapType = "halThermoSet";
|
||||||
|
$scope.device.mapId = haldevice.haldevicename + "-" + haldevice.halname + "-SetHeat";
|
||||||
|
$scope.device.onUrl = "http://" + haldevice.haladdress
|
||||||
|
+ "/HVACService!HVACCmd=Set!HVACName="
|
||||||
|
+ haldevice.haldevicename.replaceAll(" ", "%20")
|
||||||
|
+ "!HVACMode=Heat?Token="
|
||||||
|
+ $scope.bridge.settings.haltoken;
|
||||||
|
$scope.device.dimUrl = "http://" + haldevice.haladdress
|
||||||
|
+ "/HVACService!HVACCmd=Set!HVACName="
|
||||||
|
+ haldevice.haldevicename.replaceAll(" ", "%20")
|
||||||
|
+ "!HVACMode=Heat!HeatSpValue=${intensity.percent}?Token="
|
||||||
|
+ $scope.bridge.settings.haltoken;
|
||||||
|
$scope.device.offUrl = "http://" + haldevice.haladdress
|
||||||
|
+ "/HVACService!HVACCmd=Set!HVACName="
|
||||||
|
+ haldevice.haldevicename.replaceAll(" ", "%20")
|
||||||
|
+ "!HVACMode=Off?Token="
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.buildHALCoolUrls = function (haldevice) {
|
||||||
|
bridgeService.clearDevice();
|
||||||
|
$scope.device.deviceType = "thermo";
|
||||||
|
$scope.device.name = haldevice.haldevicename + " Cool";
|
||||||
|
$scope.device.targetDevice = haldevice.halname;
|
||||||
|
$scope.device.mapType = "halThermoSet";
|
||||||
|
$scope.device.mapId = haldevice.haldevicename + "-" + haldevice.halname + "-SetCool";
|
||||||
|
$scope.device.onUrl = "http://" + haldevice.haladdress
|
||||||
|
+ "/HVACService!HVACCmd=Set!HVACName="
|
||||||
|
+ haldevice.haldevicename.replaceAll(" ", "%20")
|
||||||
|
+ "!HVACMode=Cool?Token="
|
||||||
|
+ $scope.bridge.settings.haltoken;
|
||||||
|
$scope.device.dimUrl = "http://" + haldevice.haladdress
|
||||||
|
+ "/HVACService!HVACCmd=Set!HVACName="
|
||||||
|
+ haldevice.haldevicename.replaceAll(" ", "%20")
|
||||||
|
+ "!HVACMode=Cool!CoolSpValue=${intensity.percent}?Token="
|
||||||
|
+ $scope.bridge.settings.haltoken;
|
||||||
|
$scope.device.offUrl = "http://" + haldevice.haladdress
|
||||||
|
+ "/HVACService!HVACCmd=Set!HVACName="
|
||||||
|
+ haldevice.haldevicename.replaceAll(" ", "%20")
|
||||||
|
+ "!HVACMode=Off?Token="
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.buildHALAutoUrls = function (haldevice) {
|
||||||
|
bridgeService.clearDevice();
|
||||||
|
$scope.device.deviceType = "thermo";
|
||||||
|
$scope.device.name = haldevice.haldevicename + " Auto";
|
||||||
|
$scope.device.targetDevice = haldevice.halname;
|
||||||
|
$scope.device.mapType = "halThermoSet";
|
||||||
|
$scope.device.mapId = haldevice.haldevicename + "-" + haldevice.halname + "-SetAuto";
|
||||||
|
$scope.device.onUrl = "http://" + haldevice.haladdress
|
||||||
|
+ "/HVACService!HVACCmd=Set!HVACName="
|
||||||
|
+ haldevice.haldevicename.replaceAll(" ", "%20")
|
||||||
|
+ "!HVACMode=Auto?Token="
|
||||||
|
+ $scope.bridge.settings.haltoken;
|
||||||
|
$scope.device.offUrl = "http://" + haldevice.haladdress
|
||||||
|
+ "/HVACService!HVACCmd=Set!HVACName="
|
||||||
|
+ haldevice.haldevicename.replaceAll(" ", "%20")
|
||||||
|
+ "!HVACMode=Off?Token="
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.buildHALOffUrls = function (haldevice) {
|
||||||
|
bridgeService.clearDevice();
|
||||||
|
$scope.device.deviceType = "thermo";
|
||||||
|
$scope.device.name = haldevice.haldevicename + " Thermostat";
|
||||||
|
$scope.device.targetDevice = haldevice.halname;
|
||||||
|
$scope.device.mapType = "halThermoSet";
|
||||||
|
$scope.device.mapId = haldevice.haldevicename + "-" + haldevice.halname + "-TurnOff";
|
||||||
|
$scope.device.onUrl = "http://" + haldevice.haladdress
|
||||||
|
+ "/HVACService!HVACCmd=Set!HVACName="
|
||||||
|
+ haldevice.haldevicename.replaceAll(" ", "%20")
|
||||||
|
+ "!HVACMode=Auto?Token="
|
||||||
|
+ $scope.bridge.settings.haltoken;
|
||||||
|
$scope.device.offUrl = "http://" + haldevice.haladdress
|
||||||
|
+ "/HVACService!HVACCmd=Set!HVACName="
|
||||||
|
+ haldevice.haldevicename.replaceAll(" ", "%20")
|
||||||
|
+ "!HVACMode=Off?Token="
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.buildHALFanUrls = function (haldevice) {
|
||||||
|
bridgeService.clearDevice();
|
||||||
|
$scope.device.deviceType = "thermo";
|
||||||
|
$scope.device.name = haldevice.haldevicename + " Fan";
|
||||||
|
$scope.device.targetDevice = haldevice.halname;
|
||||||
|
$scope.device.mapType = "halThermoSet";
|
||||||
|
$scope.device.mapId = haldevice.haldevicename + "-" + haldevice.halname + "-SetFan";
|
||||||
|
$scope.device.onUrl = "http://" + haldevice.haladdress
|
||||||
|
+ "/HVACService!HVACCmd=Set!HVACName="
|
||||||
|
+ haldevice.haldevicename.replaceAll(" ", "%20")
|
||||||
|
+ "!FanMode=On?Token="
|
||||||
|
+ $scope.bridge.settings.haltoken;
|
||||||
|
$scope.device.offUrl = "http://" + haldevice.haladdress
|
||||||
|
+ "/HVACService!HVACCmd=Set!HVACName="
|
||||||
|
+ haldevice.haldevicename.replaceAll(" ", "%20")
|
||||||
|
+ "!FanMode=Auto?Token="
|
||||||
|
+ $scope.bridge.settings.haltoken;
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.addDevice = function () {
|
||||||
|
if($scope.device.name == "" && $scope.device.onUrl == "")
|
||||||
|
return;
|
||||||
|
bridgeService.addDevice($scope.device).then(
|
||||||
|
function () {
|
||||||
|
$scope.clearDevice();
|
||||||
|
bridgeService.viewDevices();
|
||||||
|
bridgeService.viewHalDevices();
|
||||||
|
},
|
||||||
|
function (error) {
|
||||||
|
bridgeService.displayWarn("Error adding device: " + $scope.device.name, error)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.bulkAddDevices = function(dim_control) {
|
||||||
|
var devicesList = [];
|
||||||
|
for(var i = 0; i < $scope.bulk.devices.length; i++) {
|
||||||
|
for(var x = 0; x < bridgeService.state.haldevices.length; x++) {
|
||||||
|
if(bridgeService.state.haldevices[x].haldevicename == $scope.bulk.devices[i]) {
|
||||||
|
if(bridgeService.state.haldevices[x].haldevicetype == "HVAC")
|
||||||
|
$scope.buildHALAutoUrls(bridgeService.state.haldevices[x]);
|
||||||
|
else if(bridgeService.state.haldevices[x].haldevicetype == "HOME")
|
||||||
|
$scope.buildHALHomeUrls(bridgeService.state.haldevices[x]);
|
||||||
|
else
|
||||||
|
$scope.buildDeviceUrls(bridgeService.state.haldevices[x],dim_control);
|
||||||
|
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,
|
||||||
|
contentBodyOff: $scope.device.contentBodyOff
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bridgeService.bulkAddDevice(devicesList).then(
|
||||||
|
function () {
|
||||||
|
$scope.clearDevice();
|
||||||
|
bridgeService.viewDevices();
|
||||||
|
bridgeService.viewHalDevices();
|
||||||
|
},
|
||||||
|
function (error) {
|
||||||
|
bridgeService.displayWarn("Error adding HAL 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.haldevices.length; x++) {
|
||||||
|
if($scope.bulk.devices.indexOf(bridgeService.state.haldevices[x]) < 0 && !bridgeService.findDeviceByMapId(bridgeService.state.haldevices[x].haldevicename + "-" + bridgeService.state.haldevices[x].halname, bridgeService.state.haldevices[x].halname, "halDevice"))
|
||||||
|
$scope.bulk.devices.push(bridgeService.state.haldevices[x].haldevicename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.toggleButtons = function () {
|
||||||
|
$scope.buttonsVisible = !$scope.buttonsVisible;
|
||||||
|
if($scope.buttonsVisible)
|
||||||
|
$scope.imgButtonsUrl = "glyphicon glyphicon-minus";
|
||||||
|
else
|
||||||
|
$scope.imgButtonsUrl = "glyphicon glyphicon-plus";
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.deleteDeviceByMapId = function (id, mapType) {
|
||||||
|
$scope.bridge.mapandid = { id, mapType };
|
||||||
|
ngDialog.open({
|
||||||
|
template: 'deleteMapandIdDialog',
|
||||||
|
controller: 'DeleteMapandIdDialogCtrl',
|
||||||
|
className: 'ngdialog-theme-default'
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
});
|
});
|
||||||
@@ -1282,6 +1899,63 @@ app.filter('unavailableNestItemId', function(bridgeService) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.filter('availableHueDeviceId', function(bridgeService) {
|
||||||
|
return function(input) {
|
||||||
|
var out = [];
|
||||||
|
if(input == null)
|
||||||
|
return out;
|
||||||
|
for (var i = 0; i < input.length; i++) {
|
||||||
|
if(!bridgeService.findDeviceByMapId(input[i].device.uniqueid, input[i].huename, "hueDevice")){
|
||||||
|
out.push(input[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.filter('unavailableHueDeviceId', function(bridgeService) {
|
||||||
|
return function(input) {
|
||||||
|
var out = [];
|
||||||
|
if(input == null)
|
||||||
|
return out;
|
||||||
|
for (var i = 0; i < input.length; i++) {
|
||||||
|
if(bridgeService.findDeviceByMapId(input[i].device.uniqueid, input[i].huename, "hueDevice")){
|
||||||
|
out.push(input[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.filter('availableHalDeviceId', function(bridgeService) {
|
||||||
|
return function(input) {
|
||||||
|
var out = [];
|
||||||
|
if(input == null)
|
||||||
|
return out;
|
||||||
|
for (var i = 0; i < input.length; i++) {
|
||||||
|
if(!bridgeService.findDeviceByMapId(input[i].haldevicename + "-" + input[i].halname, input[i].halname, "halDevice") &&
|
||||||
|
!bridgeService.findDeviceByMapId(input[i].haldevicename + "-" + input[i].halname + "-HomeAway", input[i].halname, "halHome") ){
|
||||||
|
out.push(input[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.filter('unavailableHalDeviceId', function(bridgeService) {
|
||||||
|
return function(input) {
|
||||||
|
var out = [];
|
||||||
|
if(input == null)
|
||||||
|
return out;
|
||||||
|
for (var i = 0; i < input.length; i++) {
|
||||||
|
if(input[i].mapType != null && bridgeService.aContainsB(input[i].mapType, "hal")){
|
||||||
|
out.push(input[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
app.filter('configuredButtons', function() {
|
app.filter('configuredButtons', function() {
|
||||||
return function(input) {
|
return function(input) {
|
||||||
var out = [];
|
var out = [];
|
||||||
|
|||||||
@@ -1,39 +1,50 @@
|
|||||||
<ul class="nav nav-pills" role="tablist">
|
|
||||||
<li role="presentation" class="active"><a href="#">Bridge Devices</a></li>
|
|
||||||
<li role="presentation"><a href="#/system">Bridge Control</a></li>
|
|
||||||
<li role="presentation"><a href="#/logs">Logs</a></li>
|
|
||||||
<li ng-if="bridge.showVera" role="presentation"><a href="#/veradevices">Vera Devices</a></li>
|
|
||||||
<li ng-if="bridge.showVera" role="presentation"><a href="#/verascenes">Vera Scenes</a></li>
|
|
||||||
<li ng-if="bridge.showHarmony" role="presentation"><a href="#/harmonyactivities">Harmony Activities</a></li>
|
|
||||||
<li ng-if="bridge.showHarmony" role="presentation"><a href="#/harmonydevices">Harmony Devices</a></li>
|
|
||||||
<li ng-if="bridge.showNest" role="presentation"><a href="#/nest">Nest</a></li>
|
|
||||||
<li role="presentation"><a href="#/editor">Manual Add</a></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<div class="panel panel-default">
|
<ul class="nav nav-pills" role="tablist">
|
||||||
<div class="panel-heading">
|
<li role="presentation" class="active"><a href="#">Bridge
|
||||||
<h2 class="panel-title">Current devices ({{bridge.devices.length}}) </h2>
|
Devices</a></li>
|
||||||
</div>
|
<li role="presentation"><a href="#/system">Bridge Control</a></li>
|
||||||
<scrollable-table watch="bridge.devices">
|
<li role="presentation"><a href="#/logs">Logs</a></li>
|
||||||
<table class="table table-bordered table-striped table-hover">
|
<li ng-if="bridge.showVera" role="presentation"><a
|
||||||
<thead>
|
href="#/veradevices">Vera Devices</a></li>
|
||||||
<tr>
|
<li ng-if="bridge.showVera" role="presentation"><a
|
||||||
<th>Row</th>
|
href="#/verascenes">Vera Scenes</a></li>
|
||||||
<th sortable-header col="id">ID</th>
|
<li ng-if="bridge.showHarmony" role="presentation"><a
|
||||||
<th sortable-header col="name">Name</th>
|
href="#/harmonyactivities">Harmony Activities</a></li>
|
||||||
<th sortable-header col="deviceType">Type</th>
|
<li ng-if="bridge.showHarmony" role="presentation"><a
|
||||||
<th sortable-header col="targetDevice">Target</th>
|
href="#/harmonydevices">Harmony Devices</a></li>
|
||||||
<th>Actions</th>
|
<li ng-if="bridge.showNest" role="presentation"><a href="#/nest">Nest</a></li>
|
||||||
</tr>
|
<li ng-if="bridge.showHue" role="presentation"><a
|
||||||
</thead>
|
href="#/huedevices">Hue Devices</a></li>
|
||||||
<tr ng-repeat="device in bridge.devices">
|
<li ng-if="bridge.showHal" role="presentation"><a
|
||||||
<td>{{$index+1}}</td>
|
href="#/haldevices">HAL Devices</a></li>
|
||||||
<td>{{device.id}}</td>
|
<li role="presentation"><a href="#/editor">Manual Add</a></li>
|
||||||
<td>{{device.name}}</td>
|
</ul>
|
||||||
<td>{{device.deviceType}}</td>
|
|
||||||
<td>{{device.targetDevice}}</td>
|
<div class="panel panel-default">
|
||||||
<td>
|
<div class="panel-heading">
|
||||||
<p>
|
<h2 class="panel-title">Current devices
|
||||||
|
({{bridge.devices.length}})</h2>
|
||||||
|
</div>
|
||||||
|
<scrollable-table watch="bridge.devices">
|
||||||
|
<table class="table table-bordered table-striped table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Row</th>
|
||||||
|
<th sortable-header col="id">ID</th>
|
||||||
|
<th sortable-header col="name">Name</th>
|
||||||
|
<th sortable-header col="deviceType">Type</th>
|
||||||
|
<th sortable-header col="targetDevice">Target</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tr ng-repeat="device in bridge.devices">
|
||||||
|
<td>{{$index+1}}</td>
|
||||||
|
<td>{{device.id}}</td>
|
||||||
|
<td>{{device.name}}</td>
|
||||||
|
<td>{{device.deviceType}}</td>
|
||||||
|
<td>{{device.targetDevice}}</td>
|
||||||
|
<td>
|
||||||
|
<p>
|
||||||
<button class="btn btn-info" type="submit"
|
<button class="btn btn-info" type="submit"
|
||||||
ng-click="testUrl(device, 'on')">Test ON</button>
|
ng-click="testUrl(device, 'on')">Test ON</button>
|
||||||
<button class="btn btn-info" type="submit"
|
<button class="btn btn-info" type="submit"
|
||||||
@@ -44,50 +55,56 @@
|
|||||||
ng-click="editDevice(device)">Edit/Copy</button>
|
ng-click="editDevice(device)">Edit/Copy</button>
|
||||||
<button class="btn btn-danger" type="submit"
|
<button class="btn btn-danger" type="submit"
|
||||||
ng-click="deleteDevice(device)">Delete</button>
|
ng-click="deleteDevice(device)">Delete</button>
|
||||||
</p>
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</scrollable-table>
|
||||||
|
</div>
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h1 class="panel-title">
|
||||||
|
Bridge Device DB Backup <a ng-click="toggleBk()"><span
|
||||||
|
class={{imgBkUrl}} aria-hidden="true"></a>
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<div ng-if="visibleBk" class="animate-if" class="panel-body">
|
||||||
|
<p>Control your backups from this area. Use the default name by hitting backup or specify your own.</p>
|
||||||
|
<form class="form-horizontal">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-xs-12 col-sm-2 control-label" for="backup-name">Backup
|
||||||
|
File Name</label>
|
||||||
|
|
||||||
|
<div class="col-xs-8 col-sm-7">
|
||||||
|
<input id="backup-name" class="form-control" type="text"
|
||||||
|
ng-model="optionalbackupname" placeholder="Optional">
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary"
|
||||||
|
ng-click="backupDeviceDb(optionalbackupname)">Backup
|
||||||
|
Device DB</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<table class="table table-bordered table-striped table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Filename</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tr ng-repeat="backup in bridge.backups">
|
||||||
|
<td>{{backup}}</td>
|
||||||
|
<td>
|
||||||
|
<button class="btn btn-danger" type="submit"
|
||||||
|
ng-click="restoreBackup(backup)">Restore</button>
|
||||||
|
<button class="btn btn-warning" type="submit"
|
||||||
|
ng-click="deleteBackup(backup)">Delete</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</scrollable-table>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="panel panel-default backup">
|
</div>
|
||||||
<div class="panel-heading">
|
|
||||||
<h1 class="panel-title">Bridge Device DB Backup <a ng-click="toggleBk()"><span class={{imgBkUrl}} aria-hidden="true"></a></h1>
|
|
||||||
</div>
|
|
||||||
<div ng-if="visibleBk" class="animate-if" class="panel-body">
|
|
||||||
<form class="form-horizontal">
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="col-xs-12 col-sm-2 control-label" for="backup-name">Backup File Name</label>
|
|
||||||
|
|
||||||
<div class="col-xs-8 col-sm-7">
|
<script type="text/ng-template" id="valueDialog">
|
||||||
<input id="backup-name" class="form-control" type="text"
|
|
||||||
ng-model="optionalbackupname" placeholder="Optional">
|
|
||||||
</div>
|
|
||||||
<button type="submit" class="btn btn-primary"
|
|
||||||
ng-click="backupDeviceDb(optionalbackupname)">Backup Device DB</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<table class="table table-bordered table-striped table-hover">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Filename</th>
|
|
||||||
<th>Actions</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tr ng-repeat="backup in bridge.backups">
|
|
||||||
<td>{{backup}}</td>
|
|
||||||
<td>
|
|
||||||
<button class="btn btn-danger" type="submit"
|
|
||||||
ng-click="restoreBackup(backup)">Restore</button>
|
|
||||||
<button class="btn btn-warning" type="submit"
|
|
||||||
ng-click="deleteBackup(backup)">Delete</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script type="text/ng-template" id="valueDialog">
|
|
||||||
<div class="ngdialog-message">
|
<div class="ngdialog-message">
|
||||||
<h2>Select value</h2>
|
<h2>Select value</h2>
|
||||||
<p>
|
<p>
|
||||||
@@ -102,4 +119,13 @@
|
|||||||
<button type="button" class="ngdialog-button ngdialog-button-primary" ng-click="setValue()">Set</button>
|
<button type="button" class="ngdialog-button ngdialog-button-primary" ng-click="setValue()">Set</button>
|
||||||
</div>
|
</div>
|
||||||
</script>
|
</script>
|
||||||
|
<script type="text/ng-template" id="deleteDialog">
|
||||||
|
<div class="ngdialog-message">
|
||||||
|
<h2>Device to Delete?</h2>
|
||||||
|
<p>{{device.name}}</p>
|
||||||
|
<p>Are you Sure?</p>
|
||||||
|
</div>
|
||||||
|
<div class="ngdialog-buttons mt">
|
||||||
|
<button type="button" class="ngdialog-button ngdialog-button-error" ng-click="deleteDevice(device)">Delete</button>
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
|
|||||||
@@ -1,175 +1,235 @@
|
|||||||
<ul class="nav nav-pills" role="tablist">
|
<ul class="nav nav-pills" role="tablist">
|
||||||
<li role="presentation"><a href="#">Bridge Devices</a></li>
|
<li role="presentation"><a href="#">Bridge Devices</a></li>
|
||||||
<li role="presentation"><a href="#/system">Bridge Control</a></li>
|
<li role="presentation"><a href="#/system">Bridge Control</a></li>
|
||||||
<li role="presentation"><a href="#/logs">Logs</a></li>
|
<li role="presentation"><a href="#/logs">Logs</a></li>
|
||||||
<li ng-if="bridge.showVera" role="presentation"><a href="#/veradevices">Vera Devices</a></li>
|
<li ng-if="bridge.showVera" role="presentation"><a
|
||||||
<li ng-if="bridge.showVera" role="presentation"><a href="#/verascenes">Vera Scenes</a></li>
|
href="#/veradevices">Vera Devices</a></li>
|
||||||
<li ng-if="bridge.showHarmony" role="presentation"><a href="#/harmonyactivities">Harmony Activities</a></li>
|
<li ng-if="bridge.showVera" role="presentation"><a
|
||||||
<li ng-if="bridge.showHarmony" role="presentation"><a href="#/harmonydevices">Harmony Devices</a></li>
|
href="#/verascenes">Vera Scenes</a></li>
|
||||||
<li ng-if="bridge.showNest" role="presentation"><a href="#/nest">Nest</a></li>
|
<li ng-if="bridge.showHarmony" role="presentation"><a
|
||||||
<li role="presentation"><a href="#/editor">Manual Add</a></li>
|
href="#/harmonyactivities">Harmony Activities</a></li>
|
||||||
<li role="presentation" class="active"><a href="#/editdevice">Edit Device</a></li>
|
<li ng-if="bridge.showHarmony" role="presentation"><a
|
||||||
</ul>
|
href="#/harmonydevices">Harmony Devices</a></li>
|
||||||
|
<li ng-if="bridge.showNest" role="presentation"><a href="#/nest">Nest</a></li>
|
||||||
|
<li ng-if="bridge.showHue" role="presentation"><a
|
||||||
|
href="#/huedevices">Hue Devices</a></li>
|
||||||
|
<li role="presentation"><a href="#/editor">Manual Add</a></li>
|
||||||
|
<li ng-if="bridge.showHal" role="presentation"><a
|
||||||
|
href="#/haldevices">HAL Devices</a></li>
|
||||||
|
<li role="presentation" class="active"><a href="#/editdevice">Edit
|
||||||
|
Device</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<div class="panel panel-default bridgeServer" ng-if="!bridge.error">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h2 class="panel-title">Edit/Copy a device</h2>
|
<h2 class="panel-title">Edit/Copy a device</h2>
|
||||||
</div>
|
</div>
|
||||||
<p class="text-muted">This screen allows the modification of many fields the bridge uses. Please use care when
|
<div class="panel-body">
|
||||||
updating these fields as you may break the settings used by the bridge to call a specific end point device.</p>
|
<p class="text-muted">This screen allows the modification of many
|
||||||
<p>When copying, update the name and select the "Add Bridge Device" Button.</p>
|
fields the bridge uses. Please use care when updating these fields as
|
||||||
<ul class="list-group">
|
you may break the settings used by the bridge to call a specific end
|
||||||
<li class="list-group-item">
|
point device.</p>
|
||||||
<form class="form-horizontal">
|
<p>When copying, update the name and select the "Add Bridge
|
||||||
<div class="form-group">
|
Device" Button.</p>
|
||||||
<label class="col-xs-12 col-sm-2 control-label" for="device-name">Name
|
</div>
|
||||||
</label>
|
<form class="form-horizontal">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-xs-12 col-sm-2 control-label" for="device-name">Name
|
||||||
|
</label>
|
||||||
|
|
||||||
<div class="col-xs-8 col-sm-7">
|
<div class="col-xs-8 col-sm-7">
|
||||||
<input type="text" class="form-control" id="device-name"
|
<input type="text" class="form-control" id="device-name"
|
||||||
ng-model="device.name" placeholder="Device Name">
|
ng-model="device.name" placeholder="Device Name">
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="col-xs-4 col-sm-2 btn btn-success" ng-click="addDevice()">
|
<button type="submit" class="col-xs-4 col-sm-2 btn btn-success"
|
||||||
Update Bridge Device</button>
|
ng-click="addDevice()">Update Bridge Device</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="col-xs-12 col-sm-2 control-label" for="device-target">Target
|
<label class="col-xs-12 col-sm-2 control-label" for="device-target">Target
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<div class="col-xs-8 col-sm-7">
|
<div class="col-xs-8 col-sm-7">
|
||||||
<input type="text" class="form-control" id="device-target"
|
<input type="text" class="form-control" id="device-target"
|
||||||
ng-model="device.targetDevice" placeholder="default">
|
ng-model="device.targetDevice" placeholder="default">
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-primary" ng-click="copyDevice()">
|
<button class="btn btn-primary" ng-click="copyDevice()">Add
|
||||||
Add Bridge Device</button>
|
Bridge Device</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<label class="col-xs-12 col-sm-2 control-label" for="device-map-type">Map Type
|
<label class="col-xs-12 col-sm-2 control-label" for="device-type">Device
|
||||||
</label>
|
Type </label>
|
||||||
|
|
||||||
<div class="col-xs-8 col-sm-7">
|
<div class="col-xs-8 col-sm-7">
|
||||||
<select name="device-map-type" id="device-map-type" ng-model="device.mapType">
|
<select name="device-type" id="device-type"
|
||||||
<option value="">---Please select---</option> <!-- not selected / blank option -->
|
ng-model="device.deviceType">
|
||||||
<option value="veraDevice">Vera Device</option>
|
<option value="">---Types if needed---</option>
|
||||||
<option value="veraScene">Vera Scene</option>
|
<!-- not selected / blank option -->
|
||||||
<option value="harmonyActivity">Harmony Activity</option>
|
<option value="custom">Custom</option>
|
||||||
<option value="harmonyButton">Harmony Button</option>
|
<option value="UDP">UDP</option>
|
||||||
<option value="nestHomeAway">Nest Home Status</option>
|
<option value="TCP">TCP</option>
|
||||||
<option value="nestThermoSet">Nest Thermostat</option>
|
<option value="exec">Execute Script/Program</option>
|
||||||
</select>
|
<option value="switch">Switch</option>
|
||||||
</div>
|
<option value="scene">Scene</option>
|
||||||
<button class="btn btn-danger" ng-click="clearDevice()">
|
<option value="macro">Macro</option>
|
||||||
Clear Device</button>
|
<option value="group">Group</option>
|
||||||
</div>
|
<option value="activity">Activity</option>
|
||||||
|
<option value="button">Button</option>
|
||||||
|
<option value="thermo">Thermo</option>
|
||||||
|
<option value="passthru">Pass Thru</option>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div ng-if="device.mapType" class="form-group">
|
</div>
|
||||||
<label class="col-xs-12 col-sm-2 control-label" for="device-map-id">Map ID
|
</div>
|
||||||
</label>
|
<div class="form-group">
|
||||||
|
<div class="row">
|
||||||
|
<label class="col-xs-12 col-sm-2 control-label"
|
||||||
|
for="device-map-type">Map Type </label>
|
||||||
|
|
||||||
<div class="col-xs-8 col-sm-7">
|
<div class="col-xs-8 col-sm-7">
|
||||||
<input type="text" class="form-control" id="device-map-id"
|
<select name="device-map-type" id="device-map-type"
|
||||||
ng-model="device.mapId" placeholder="1111">
|
ng-model="device.mapType">
|
||||||
</div>
|
<option value="">---Please select---</option>
|
||||||
|
<!-- not selected / blank option -->
|
||||||
|
<option value="veraDevice">Vera Device</option>
|
||||||
|
<option value="veraScene">Vera Scene</option>
|
||||||
|
<option value="harmonyActivity">Harmony Activity</option>
|
||||||
|
<option value="harmonyButton">Harmony Button</option>
|
||||||
|
<option value="nestHomeAway">Nest Home Status</option>
|
||||||
|
<option value="nestThermoSet">Nest Thermostat</option>
|
||||||
|
<option value="hueDevice">Hue Device</option>
|
||||||
|
<option value="halDevice">HAL Device</option>
|
||||||
|
<option value="halHome">HAL Home Status</option>
|
||||||
|
<option value="halThermoSet">HAL Thermostat</option>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<button class="btn btn-danger" ng-click="clearDevice()">
|
||||||
<div class="row">
|
Clear Device</button>
|
||||||
<label class="col-xs-12 col-sm-2 control-label" for="device-on-url">On
|
</div>
|
||||||
URL </label>
|
</div>
|
||||||
|
<div ng-if="device.mapType" class="form-group">
|
||||||
|
<label class="col-xs-12 col-sm-2 control-label" for="device-map-id">Map
|
||||||
|
ID </label>
|
||||||
|
|
||||||
<div class="col-xs-8 col-sm-7">
|
<div class="col-xs-8 col-sm-7">
|
||||||
<textarea rows="3" class="form-control" id="device-on-url"
|
<input type="text" class="form-control" id="device-map-id"
|
||||||
ng-model="device.onUrl" placeholder="URL to turn device on"></textarea>
|
ng-model="device.mapId" placeholder="1111">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="form-group">
|
||||||
<div class="form-group">
|
<div class="row">
|
||||||
<div class="row">
|
<label class="col-xs-12 col-sm-2 control-label" for="device-on-url">On
|
||||||
<label class="col-xs-12 col-sm-2 control-label" for="device-dim-url">Dim
|
URL </label>
|
||||||
URL </label>
|
|
||||||
|
|
||||||
<div class="col-xs-8 col-sm-7">
|
<div class="col-xs-8 col-sm-7">
|
||||||
<textarea rows="3" class="form-control" id="device-dim-url"
|
<textarea rows="3" class="form-control" id="device-on-url"
|
||||||
ng-model="device.dimUrl" placeholder="URL to dim device"></textarea>
|
ng-model="device.onUrl" placeholder="URL to turn device on"></textarea>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
</div>
|
||||||
<div class="row">
|
</div>
|
||||||
<label class="col-xs-12 col-sm-2 control-label"
|
<div class="form-group">
|
||||||
for="device-off-url">Off URL </label>
|
<div class="row">
|
||||||
|
<label class="col-xs-12 col-sm-2 control-label" for="device-dim-url">Dim
|
||||||
|
URL </label>
|
||||||
|
|
||||||
<div class="col-xs-8 col-sm-7">
|
<div class="col-xs-8 col-sm-7">
|
||||||
<textarea rows="3" class="form-control" id="device-off-url"
|
<textarea rows="3" class="form-control" id="device-dim-url"
|
||||||
ng-model="device.offUrl" placeholder="URL to turn device off"></textarea>
|
ng-model="device.dimUrl" placeholder="URL to dim device"></textarea>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
</div>
|
||||||
<div class="row">
|
</div>
|
||||||
<label class="col-xs-12 col-sm-2 control-label" for="device-http-verb">Http Verb
|
<div class="form-group">
|
||||||
</label>
|
<div class="row">
|
||||||
|
<label class="col-xs-12 col-sm-2 control-label" for="device-off-url">Off
|
||||||
|
URL </label>
|
||||||
|
|
||||||
<div class="col-xs-8 col-sm-7">
|
<div class="col-xs-8 col-sm-7">
|
||||||
<select name="device-http-verb" id="device-http-verb" ng-model="device.httpVerb">
|
<textarea rows="3" class="form-control" id="device-off-url"
|
||||||
<option value="">---Please select---</option> <!-- not selected / blank option -->
|
ng-model="device.offUrl" placeholder="URL to turn device off"></textarea>
|
||||||
<option value="GET">GET</option>
|
|
||||||
<option value="PUT">PUT</option>
|
|
||||||
<option value="POST">POST</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div ng-if="device.httpVerb" class="form-group">
|
</div>
|
||||||
<div class="row">
|
</div>
|
||||||
<label class="col-xs-12 col-sm-2 control-label" for="device-content-type">Content Type
|
<div class="form-group">
|
||||||
</label>
|
<div class="row">
|
||||||
|
<label class="col-xs-12 col-sm-2 control-label" for="device-headers">HTTP
|
||||||
|
Headers </label>
|
||||||
|
|
||||||
<div class="col-xs-8 col-sm-7">
|
<div class="col-xs-8 col-sm-7">
|
||||||
<select name="device-content-type" id="device-content-type" ng-model="device.contentType">
|
<textarea rows="3" class="form-control" id="device-headers"
|
||||||
<option value="">---Please select---</option> <!-- not selected / blank option -->
|
ng-model="device.headers"
|
||||||
<option value="application/atom+xml">application/atom+xml</option>
|
placeholder="format like: [{"name":"A name","value":"a value"}]"></textarea>
|
||||||
<option value="application/x-www-form-urlencoded">application/x-www-form-urlencoded</option>
|
|
||||||
<option value="application/json">application/json</option>
|
|
||||||
<option value="application/octet-stream">application/octet-stream</option>
|
|
||||||
<option value="application/svg+xml">application/svg+xml</option>
|
|
||||||
<option value="application/xhtml+xml">application/xhtml+xml</option>
|
|
||||||
<option value="application/xml">application/xml</option>
|
|
||||||
<option value="*">*</option>
|
|
||||||
<option value="multipart/form-data">multipart/form-data</option>
|
|
||||||
<option value="text/html">text/html</option>
|
|
||||||
<option value="text/plain">text/plain</option>
|
|
||||||
<option value="text/xml">text/xml</option>
|
|
||||||
<option value="*/*">*/*</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div ng-if="device.httpVerb" class="form-group">
|
</div>
|
||||||
<div class="row">
|
</div>
|
||||||
<label class="col-xs-12 col-sm-2 control-label"
|
<div class="form-group">
|
||||||
for="device-content-body">Content Body On</label>
|
<div class="row">
|
||||||
|
<label class="col-xs-12 col-sm-2 control-label"
|
||||||
|
for="device-http-verb">Http Verb </label>
|
||||||
|
|
||||||
<div class="col-xs-8 col-sm-7">
|
<div class="col-xs-8 col-sm-7">
|
||||||
<textarea rows="3" class="form-control" id="device-content-body"
|
<select name="device-http-verb" id="device-http-verb"
|
||||||
ng-model="device.contentBody" placeholder="Content Body On for specific GET/PUT/POST type"></textarea>
|
ng-model="device.httpVerb">
|
||||||
</div>
|
<option value="">---Please select---</option>
|
||||||
<div class="clearfix visible-xs"></div>
|
<!-- not selected / blank option -->
|
||||||
</div>
|
<option value="GET">GET</option>
|
||||||
|
<option value="PUT">PUT</option>
|
||||||
|
<option value="POST">POST</option>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div ng-if="device.httpVerb" class="form-group">
|
</div>
|
||||||
<div class="row">
|
</div>
|
||||||
<label class="col-xs-12 col-sm-2 control-label"
|
<div ng-if="device.httpVerb" class="form-group">
|
||||||
for="device-content-body-off">Content Body Off</label>
|
<div class="row">
|
||||||
|
<label class="col-xs-12 col-sm-2 control-label"
|
||||||
|
for="device-content-type">Content Type </label>
|
||||||
|
|
||||||
<div class="col-xs-8 col-sm-7">
|
<div class="col-xs-8 col-sm-7">
|
||||||
<textarea rows="3" class="form-control" id="device-content-body-off"
|
<select name="device-content-type" id="device-content-type"
|
||||||
ng-model="device.contentBodyOff" placeholder="Content Body Off for specific GET/PUT/POST type"></textarea>
|
ng-model="device.contentType">
|
||||||
</div>
|
<option value="">---Please select---</option>
|
||||||
<div class="clearfix visible-xs"></div>
|
<!-- not selected / blank option -->
|
||||||
</div>
|
<option value="application/atom+xml">application/atom+xml</option>
|
||||||
|
<option value="application/x-www-form-urlencoded">application/x-www-form-urlencoded</option>
|
||||||
|
<option value="application/json">application/json</option>
|
||||||
|
<option value="application/octet-stream">application/octet-stream</option>
|
||||||
|
<option value="application/svg+xml">application/svg+xml</option>
|
||||||
|
<option value="application/xhtml+xml">application/xhtml+xml</option>
|
||||||
|
<option value="application/xml">application/xml</option>
|
||||||
|
<option value="*">*</option>
|
||||||
|
<option value="multipart/form-data">multipart/form-data</option>
|
||||||
|
<option value="text/html">text/html</option>
|
||||||
|
<option value="text/plain">text/plain</option>
|
||||||
|
<option value="text/xml">text/xml</option>
|
||||||
|
<option value="*/*">*/*</option>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</div>
|
||||||
</li>
|
</div>
|
||||||
</ul>
|
<div ng-if="device.httpVerb" class="form-group">
|
||||||
</div>
|
<div class="row">
|
||||||
|
<label class="col-xs-12 col-sm-2 control-label"
|
||||||
|
for="device-content-body">Content Body On</label>
|
||||||
|
|
||||||
|
<div class="col-xs-8 col-sm-7">
|
||||||
|
<textarea rows="3" class="form-control" id="device-content-body"
|
||||||
|
ng-model="device.contentBody"
|
||||||
|
placeholder="Content Body On for specific GET/PUT/POST type"></textarea>
|
||||||
|
</div>
|
||||||
|
<div class="clearfix visible-xs"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div ng-if="device.httpVerb" class="form-group">
|
||||||
|
<div class="row">
|
||||||
|
<label class="col-xs-12 col-sm-2 control-label"
|
||||||
|
for="device-content-body-off">Content Body Off</label>
|
||||||
|
|
||||||
|
<div class="col-xs-8 col-sm-7">
|
||||||
|
<textarea rows="3" class="form-control"
|
||||||
|
id="device-content-body-off" ng-model="device.contentBodyOff"
|
||||||
|
placeholder="Content Body Off for specific GET/PUT/POST type"></textarea>
|
||||||
|
</div>
|
||||||
|
<div class="clearfix visible-xs"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
@@ -1,199 +1,250 @@
|
|||||||
<ul class="nav nav-pills" role="tablist">
|
<ul class="nav nav-pills" role="tablist">
|
||||||
<li role="presentation"><a href="#">Bridge Devices</a></li>
|
<li role="presentation"><a href="#">Bridge Devices</a></li>
|
||||||
<li role="presentation"><a href="#/system">Bridge Control</a></li>
|
<li role="presentation"><a href="#/system">Bridge Control</a></li>
|
||||||
<li role="presentation"><a href="#/logs">Logs</a></li>
|
<li role="presentation"><a href="#/logs">Logs</a></li>
|
||||||
<li ng-if="bridge.showVera" role="presentation"><a href="#/veradevices">Vera Devices</a></li>
|
<li ng-if="bridge.showVera" role="presentation"><a
|
||||||
<li ng-if="bridge.showVera" role="presentation"><a href="#/verascenes">Vera Scenes</a></li>
|
href="#/veradevices">Vera Devices</a></li>
|
||||||
<li ng-if="bridge.showHarmony" role="presentation"><a href="#/harmonyactivities">Harmony Activities</a></li>
|
<li ng-if="bridge.showVera" role="presentation"><a
|
||||||
<li ng-if="bridge.showHarmony" role="presentation"><a href="#/harmonydevices">Harmony Devices</a></li>
|
href="#/verascenes">Vera Scenes</a></li>
|
||||||
<li ng-if="bridge.showNest" role="presentation"><a href="#/nest">Nest</a></li>
|
<li ng-if="bridge.showHarmony" role="presentation"><a
|
||||||
<li role="presentation" class="active"><a href="#/editor">Manual Add</a></li>
|
href="#/harmonyactivities">Harmony Activities</a></li>
|
||||||
</ul>
|
<li ng-if="bridge.showHarmony" role="presentation"><a
|
||||||
|
href="#/harmonydevices">Harmony Devices</a></li>
|
||||||
|
<li ng-if="bridge.showNest" role="presentation"><a href="#/nest">Nest</a></li>
|
||||||
|
<li ng-if="bridge.showHue" role="presentation"><a
|
||||||
|
href="#/huedevices">Hue Devices</a></li>
|
||||||
|
<li ng-if="bridge.showHal" role="presentation"><a
|
||||||
|
href="#/haldevices">HAL Devices</a></li>
|
||||||
|
<li role="presentation" class="active"><a href="#/editor">Manual
|
||||||
|
Add</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<div class="panel panel-default bridgeServer" ng-if="bridge.showVera">
|
<div ng-if="bridge.showVera" class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h2 class="panel-title">Generate a new device/scene/control point</h2>
|
<h2 class="panel-title">Generate a new device/scene/control point</h2>
|
||||||
</div>
|
</div>
|
||||||
<ul class="list-group">
|
<div class="panel-body">
|
||||||
<li class="list-group-item">
|
<p class="text-muted">You can generate on/off URLs by filling in
|
||||||
<p class="text-muted">You can generate on/off URLs by filling in
|
the Vera server URL, port, and device ID; or you can fill them out
|
||||||
the Vera server URL, port, and device ID; or you can fill them out
|
manually in the lower section.</p>
|
||||||
manually in the lower section.</p>
|
</div>
|
||||||
|
<form class="form-horizontal">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-xs-12 col-sm-2 control-label" for="vera-base">Vera
|
||||||
|
Server URL </label>
|
||||||
|
|
||||||
<form class="form-horizontal">
|
<div class="col-xs-8 col-sm-7">
|
||||||
<div class="form-group">
|
<input type="text" class="form-control" id="vera-base"
|
||||||
<label class="col-xs-12 col-sm-2 control-label" for="vera-base">Vera
|
ng-model="vera.base"
|
||||||
Server URL </label>
|
placeholder="Vera URL (e.g. http://192.168.1.100)">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-xs-2 col-sm-2 control-label" for="vera-port">Vera
|
||||||
|
Request Port </label>
|
||||||
|
|
||||||
<div class="col-xs-8 col-sm-7">
|
<div class="col-xs-10 col-sm-2">
|
||||||
<input type="text" class="form-control" id="vera-base"
|
<input type="text" class="form-control" id="vera-port"
|
||||||
ng-model="vera.base"
|
ng-model="vera.port" placeholder="Vera Port (typically 3480)">
|
||||||
placeholder="Vera URL (e.g. http://192.168.1.100)">
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="col-xs-2 col-sm-2 control-label" for="vera-port">Vera
|
|
||||||
Request Port </label>
|
|
||||||
|
|
||||||
<div class="col-xs-10 col-sm-2">
|
<label class="col-xs-2 col-sm-2 control-label" for="vera-id">Device
|
||||||
<input type="text" class="form-control" id="vera-port"
|
ID </label>
|
||||||
ng-model="vera.port" placeholder="Vera Port (typically 3480)">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<label class="col-xs-2 col-sm-2 control-label" for="vera-id">Device
|
<div class="col-xs-10 col-sm-2">
|
||||||
ID </label>
|
<input type="text" class="form-control" id="vera-id"
|
||||||
|
ng-model="vera.id" placeholder="ID">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-xs-2 col-sm-2 control-label"
|
||||||
|
for="device-dim-control">Device Dim Control</label>
|
||||||
|
|
||||||
<div class="col-xs-10 col-sm-2">
|
<div class="col-xs-10 col-sm-2">
|
||||||
<input type="text" class="form-control" id="vera-id"
|
<select name="device-dim-control" id="device-dim-control"
|
||||||
ng-model="vera.id" placeholder="ID">
|
ng-model="device_dim_control">
|
||||||
</div>
|
<option value="">none</option>
|
||||||
</div>
|
<option value="${intensity..byte}">Pass-thru Value</option>
|
||||||
<div class="form-group">
|
<option value="${intensity.percent}">Percentage</option>
|
||||||
<label class="col-xs-2 col-sm-2 control-label" for="device-dim-control">Device Dim Control</label>
|
<option value="${intensity.math(X*1)}">Custom Math</option>
|
||||||
|
</select>
|
||||||
<div class="col-xs-10 col-sm-2">
|
</div>
|
||||||
<select name="device-dim-control" id="device-dim-control" ng-model="device_dim_control">
|
</div>
|
||||||
<option value="">none</option>
|
<div class="form-group">
|
||||||
<option value="${intensity..byte}">Pass-thru Value</option>
|
<button type="submit"
|
||||||
<option value="${intensity.percent}">Percentage</option>
|
ng-click="buildUrlsUsingDevice(device_dim_control)"
|
||||||
<option value="${intensity.math(X*1)}">Custom Math</option>
|
class="col-xs-2 col-sm-2 col-xs-offset-2 col-sm-offset-2 btn btn-success">Generate
|
||||||
</select>
|
Device URLs</button>
|
||||||
</div>
|
<button type="submit" ng-click="buildUrlsUsingScene()"
|
||||||
</div>
|
class="col-xs-2 col-sm-2 col-xs-offset-2 col-sm-offset-2 btn btn-success">Generate
|
||||||
<div class="form-group">
|
Scene URLs</button>
|
||||||
<button type="submit" ng-click="buildUrlsUsingDevice(device_dim_control)"
|
</div>
|
||||||
class="col-xs-2 col-sm-2 col-xs-offset-2 col-sm-offset-2 btn btn-success">Generate Device
|
</form>
|
||||||
URLs</button>
|
|
||||||
<button type="submit" ng-click="buildUrlsUsingScene()"
|
|
||||||
class="col-xs-2 col-sm-2 col-xs-offset-2 col-sm-offset-2 btn btn-success">Generate Scene
|
|
||||||
URLs</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="panel panel-default bridgeServer" ng-if="!bridge.error">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h2 class="panel-title">Add a new device</h2>
|
<h2 class="panel-title">Add a new device</h2>
|
||||||
</div>
|
</div>
|
||||||
<p class="text-muted">This area allows you to create any http or udp call to an endpoint. You can use the default GET or select
|
<div class="panel-body">
|
||||||
the http verb type below and configure a payload for either on or off methods. Currently, https is not supported.</p>
|
<p class="text-muted">This area allows you to create any http or
|
||||||
<ul class="list-group">
|
udp call to an endpoint. You can use the default GET or select the
|
||||||
<li class="list-group-item">
|
http verb type below and configure a payload for either on, dim or
|
||||||
<form class="form-horizontal">
|
off methods. Currently, https is not supported. For Execution of a
|
||||||
<div class="form-group">
|
script or program, plese fill in the path. All manually entered calls
|
||||||
<div class="row">
|
can use Json notation of array with [{"item":"the
|
||||||
<label class="col-xs-12 col-sm-2 control-label" for="device-name">Name
|
payload"},{"item":"another payload"}] to
|
||||||
</label>
|
execute multiple entries. Adding the value replacements
|
||||||
|
(${intensity..byte},${intensity.percent},${intensity.math(X*1)}) will
|
||||||
|
also work.</p>
|
||||||
|
</div>
|
||||||
|
<form class="form-horizontal">
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="row">
|
||||||
|
<label class="col-xs-12 col-sm-2 control-label" for="device-name">Name
|
||||||
|
</label>
|
||||||
|
|
||||||
<div class="col-xs-8 col-sm-7">
|
<div class="col-xs-8 col-sm-7">
|
||||||
<input type="text" class="form-control" id="device-name"
|
<input type="text" class="form-control" id="device-name"
|
||||||
ng-model="device.name" placeholder="Device Name">
|
ng-model="device.name" placeholder="Device Name">
|
||||||
</div>
|
|
||||||
<button type="submit" class="col-xs-4 col-sm-2 btn btn-primary" ng-click="addDevice()">
|
|
||||||
Add Bridge Device</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<button type="submit" class="col-xs-4 col-sm-2 btn btn-primary"
|
||||||
<div class="row">
|
ng-click="addDevice()">Add Bridge Device</button>
|
||||||
<label class="col-xs-12 col-sm-2 control-label" for="device-on-url">On
|
</div>
|
||||||
URL </label>
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="row">
|
||||||
|
<label class="col-xs-12 col-sm-2 control-label" for="device-type">Device
|
||||||
|
Type </label>
|
||||||
|
|
||||||
<div class="col-xs-8 col-sm-7">
|
<div class="col-xs-8 col-sm-7">
|
||||||
<textarea rows="3" class="form-control" id="device-on-url"
|
<select name="device-type" id="device-type"
|
||||||
ng-model="device.onUrl" placeholder="URL to turn device on"></textarea>
|
ng-model="device.deviceType">
|
||||||
</div>
|
<option value="">---Types if needed---</option>
|
||||||
<button class="btn btn-danger" ng-click="clearDevice()">
|
<!-- not selected / blank option -->
|
||||||
Clear Device</button>
|
<option value="custom">Custom</option>
|
||||||
</div>
|
<option value="UDP">UDP</option>
|
||||||
|
<option value="TCP">TCP</option>
|
||||||
|
<option value="exec">Execute Script/Program</option>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
</div>
|
||||||
<div class="row">
|
</div>
|
||||||
<label class="col-xs-12 col-sm-2 control-label" for="device-dim-url">Dim
|
<div class="form-group">
|
||||||
URL </label>
|
<div class="row">
|
||||||
|
<label class="col-xs-12 col-sm-2 control-label" for="device-on-url">On
|
||||||
|
URL </label>
|
||||||
|
|
||||||
<div class="col-xs-8 col-sm-7">
|
<div class="col-xs-8 col-sm-7">
|
||||||
<textarea rows="3" class="form-control" id="device-dim-url"
|
<textarea rows="3" class="form-control" id="device-on-url"
|
||||||
ng-model="device.dimUrl" placeholder="URL to dim device"></textarea>
|
ng-model="device.onUrl" placeholder="URL to turn device on"></textarea>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<button class="btn btn-danger" ng-click="clearDevice()">
|
||||||
<div class="row">
|
Clear Device</button>
|
||||||
<label class="col-xs-12 col-sm-2 control-label"
|
</div>
|
||||||
for="device-off-url">Off URL </label>
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="row">
|
||||||
|
<label class="col-xs-12 col-sm-2 control-label" for="device-dim-url">Dim
|
||||||
|
URL </label>
|
||||||
|
|
||||||
<div class="col-xs-8 col-sm-7">
|
<div class="col-xs-8 col-sm-7">
|
||||||
<textarea rows="3" class="form-control" id="device-off-url"
|
<textarea rows="3" class="form-control" id="device-dim-url"
|
||||||
ng-model="device.offUrl" placeholder="URL to turn device off"></textarea>
|
ng-model="device.dimUrl" placeholder="URL to dim device"></textarea>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
</div>
|
||||||
<div class="row">
|
</div>
|
||||||
<label class="col-xs-12 col-sm-2 control-label" for="device-http-verb">Http Verb
|
<div class="form-group">
|
||||||
</label>
|
<div class="row">
|
||||||
|
<label class="col-xs-12 col-sm-2 control-label" for="device-off-url">Off
|
||||||
|
URL </label>
|
||||||
|
|
||||||
<div class="col-xs-8 col-sm-7">
|
<div class="col-xs-8 col-sm-7">
|
||||||
<select name="device-http-verb" id="device-http-verb" ng-model="device.httpVerb">
|
<textarea rows="3" class="form-control" id="device-off-url"
|
||||||
<option value="">---Please select---</option> <!-- not selected / blank option -->
|
ng-model="device.offUrl" placeholder="URL to turn device off"></textarea>
|
||||||
<option value="GET">GET</option>
|
|
||||||
<option value="PUT">PUT</option>
|
|
||||||
<option value="POST">POST</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div ng-if="device.httpVerb" class="form-group">
|
</div>
|
||||||
<div class="row">
|
</div>
|
||||||
<label class="col-xs-12 col-sm-2 control-label" for="device-content-type">Content Type
|
<div class="form-group">
|
||||||
</label>
|
<div class="row">
|
||||||
|
<label class="col-xs-12 col-sm-2 control-label" for="device-headers">HTTP
|
||||||
|
Headers </label>
|
||||||
|
|
||||||
<div class="col-xs-8 col-sm-7">
|
<div class="col-xs-8 col-sm-7">
|
||||||
<select name="device-content-type" id="device-content-type" ng-model="device.contentType">
|
<textarea rows="3" class="form-control" id="device-headers"
|
||||||
<option value="">---Please select---</option> <!-- not selected / blank option -->
|
ng-model="device.headers"
|
||||||
<option value="application/atom+xml">application/atom+xml</option>
|
placeholder="format like: [{"name":"A name","value":"a value"}]"></textarea>
|
||||||
<option value="application/x-www-form-urlencoded">application/x-www-form-urlencoded</option>
|
|
||||||
<option value="application/json">application/json</option>
|
|
||||||
<option value="application/octet-stream">application/octet-stream</option>
|
|
||||||
<option value="application/svg+xml">application/svg+xml</option>
|
|
||||||
<option value="application/xhtml+xml">application/xhtml+xml</option>
|
|
||||||
<option value="application/xml">application/xml</option>
|
|
||||||
<option value="*">*</option>
|
|
||||||
<option value="multipart/form-data">multipart/form-data</option>
|
|
||||||
<option value="text/html">text/html</option>
|
|
||||||
<option value="text/plain">text/plain</option>
|
|
||||||
<option value="text/xml">text/xml</option>
|
|
||||||
<option value="*/*">*/*</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div ng-if="device.httpVerb" class="form-group">
|
</div>
|
||||||
<div class="row">
|
</div>
|
||||||
<label class="col-xs-12 col-sm-2 control-label"
|
<div class="form-group">
|
||||||
for="device-content-body">Content Body On</label>
|
<div class="row">
|
||||||
|
<label class="col-xs-12 col-sm-2 control-label"
|
||||||
|
for="device-http-verb">Http Verb </label>
|
||||||
|
|
||||||
<div class="col-xs-8 col-sm-7">
|
<div class="col-xs-8 col-sm-7">
|
||||||
<textarea rows="3" class="form-control" id="device-content-body"
|
<select name="device-http-verb" id="device-http-verb"
|
||||||
ng-model="device.contentBody" placeholder="Content Body On for specific GET/PUT/POST type"></textarea>
|
ng-model="device.httpVerb">
|
||||||
</div>
|
<option value="">---Please select---</option>
|
||||||
<div class="clearfix visible-xs"></div>
|
<!-- not selected / blank option -->
|
||||||
</div>
|
<option value="GET">GET</option>
|
||||||
|
<option value="PUT">PUT</option>
|
||||||
|
<option value="POST">POST</option>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div ng-if="device.httpVerb" class="form-group">
|
</div>
|
||||||
<div class="row">
|
</div>
|
||||||
<label class="col-xs-12 col-sm-2 control-label"
|
<div ng-if="device.httpVerb" class="form-group">
|
||||||
for="device-content-body-off">Content Body Off</label>
|
<div class="row">
|
||||||
|
<label class="col-xs-12 col-sm-2 control-label"
|
||||||
|
for="device-content-type">Content Type </label>
|
||||||
|
|
||||||
<div class="col-xs-8 col-sm-7">
|
<div class="col-xs-8 col-sm-7">
|
||||||
<textarea rows="3" class="form-control" id="device-content-body-off"
|
<select name="device-content-type" id="device-content-type"
|
||||||
ng-model="device.contentBodyOff" placeholder="Content Body Off for specific GET/PUT/POST type"></textarea>
|
ng-model="device.contentType">
|
||||||
</div>
|
<option value="">---Please select---</option>
|
||||||
<div class="clearfix visible-xs"></div>
|
<!-- not selected / blank option -->
|
||||||
</div>
|
<option value="application/atom+xml">application/atom+xml</option>
|
||||||
|
<option value="application/x-www-form-urlencoded">application/x-www-form-urlencoded</option>
|
||||||
|
<option value="application/json">application/json</option>
|
||||||
|
<option value="application/octet-stream">application/octet-stream</option>
|
||||||
|
<option value="application/svg+xml">application/svg+xml</option>
|
||||||
|
<option value="application/xhtml+xml">application/xhtml+xml</option>
|
||||||
|
<option value="application/xml">application/xml</option>
|
||||||
|
<option value="*">*</option>
|
||||||
|
<option value="multipart/form-data">multipart/form-data</option>
|
||||||
|
<option value="text/html">text/html</option>
|
||||||
|
<option value="text/plain">text/plain</option>
|
||||||
|
<option value="text/xml">text/xml</option>
|
||||||
|
<option value="*/*">*/*</option>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</div>
|
||||||
</li>
|
</div>
|
||||||
</ul>
|
<div ng-if="device.httpVerb" class="form-group">
|
||||||
</div>
|
<div class="row">
|
||||||
|
<label class="col-xs-12 col-sm-2 control-label"
|
||||||
|
for="device-content-body">Content Body On</label>
|
||||||
|
|
||||||
|
<div class="col-xs-8 col-sm-7">
|
||||||
|
<textarea rows="3" class="form-control" id="device-content-body"
|
||||||
|
ng-model="device.contentBody"
|
||||||
|
placeholder="Content Body On for specific GET/PUT/POST type"></textarea>
|
||||||
|
</div>
|
||||||
|
<div class="clearfix visible-xs"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div ng-if="device.httpVerb" class="form-group">
|
||||||
|
<div class="row">
|
||||||
|
<label class="col-xs-12 col-sm-2 control-label"
|
||||||
|
for="device-content-body-off">Content Body Off</label>
|
||||||
|
|
||||||
|
<div class="col-xs-8 col-sm-7">
|
||||||
|
<textarea rows="3" class="form-control"
|
||||||
|
id="device-content-body-off" ng-model="device.contentBodyOff"
|
||||||
|
placeholder="Content Body Off for specific GET/PUT/POST type"></textarea>
|
||||||
|
</div>
|
||||||
|
<div class="clearfix visible-xs"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
217
src/main/resources/public/views/haldevice.html
Normal file
217
src/main/resources/public/views/haldevice.html
Normal file
@@ -0,0 +1,217 @@
|
|||||||
|
<ul class="nav nav-pills" role="tablist">
|
||||||
|
<li role="presentation"><a href="#">Bridge Devices</a></li>
|
||||||
|
<li role="presentation"><a href="#/system">Bridge Control</a></li>
|
||||||
|
<li role="presentation"><a href="#/logs">Logs</a></li>
|
||||||
|
<li ng-if="bridge.showVera" role="presentation"><a
|
||||||
|
href="#/veradevices">Vera Devices</a></li>
|
||||||
|
<li ng-if="bridge.showVera" role="presentation"><a
|
||||||
|
href="#/verascenes">Vera Scenes</a></li>
|
||||||
|
<li ng-if="bridge.showHarmony" role="presentation"><a
|
||||||
|
href="#/harmonyactivities">Harmony Activities</a></li>
|
||||||
|
<li ng-if="bridge.showHarmony" role="presentation"><a
|
||||||
|
href="#/harmonydevices">Harmony Devices</a></li>
|
||||||
|
<li ng-if="bridge.showHAL" role="presentation"><a href="#/HAL">HAL</a></li>
|
||||||
|
<li ng-if="bridge.showHue" role="presentation"><a
|
||||||
|
href="#/huedevices">Hue Devices</a></li>
|
||||||
|
<li role="presentation" class="active"><a href="#/haldevices">HAL
|
||||||
|
Devices</a></li>
|
||||||
|
<li role="presentation"><a href="#/editor">Manual Add</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h2 class="panel-title">HAL Device List
|
||||||
|
({{bridge.haldevices.length}})</h2>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<p class="text-muted">For any HAL Device, use the action buttons
|
||||||
|
to generate the device addition information below automatically. Then
|
||||||
|
you can modify the name to anything you want that will be the keyword
|
||||||
|
for Alexa. 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.</p>
|
||||||
|
<p>
|
||||||
|
Also, use this select menu for which type of dim control you would
|
||||||
|
like to be generated: <select name="device-dim-control"
|
||||||
|
id="device-dim-control" ng-model="device_dim_control">
|
||||||
|
<option value="">none</option>
|
||||||
|
<option value="${intensity.byte}">Pass-thru Value</option>
|
||||||
|
<option value="${intensity.percent}">Percentage</option>
|
||||||
|
<option value="${intensity.math(X*1)}">Custom Math</option>
|
||||||
|
</select>
|
||||||
|
</p>
|
||||||
|
<p>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.</p>
|
||||||
|
</div>
|
||||||
|
<scrollable-table watch="bridge.haldevices">
|
||||||
|
<table class="table table-bordered table-striped table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Row</th>
|
||||||
|
<th sortable-header col="name">
|
||||||
|
<span><input type="checkbox" name="selectAll"
|
||||||
|
value="{{selectAll}}"
|
||||||
|
ng-checked="selectAll"
|
||||||
|
ng-click="toggleSelectAll()"> Name</span></th>
|
||||||
|
<th sortable-header col="category">Category</th>
|
||||||
|
<th sortable-header col="halname">HAL</th>
|
||||||
|
<th>On Button</th>
|
||||||
|
<th>Off Button</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tr ng-repeat="haldevice in bridge.haldevices | availableHalDeviceId">
|
||||||
|
<td>{{$index+1}}</td>
|
||||||
|
<td><input type="checkbox" name="bulk.devices[]"
|
||||||
|
value="{{haldevice.haldevicename}}"
|
||||||
|
ng-checked="bulk.devices.indexOf(haldevice.haldevicename) > -1"
|
||||||
|
ng-click="toggleSelection(haldevice.haldevicename)">
|
||||||
|
{{haldevice.haldevicename}}</td>
|
||||||
|
<td>{{haldevice.haldevicetype}}</td>
|
||||||
|
<td>{{haldevice.halname}}</td>
|
||||||
|
<td>
|
||||||
|
<select name="button-on" id="button-on" ng-model="button_on">
|
||||||
|
<option ng-repeat="aButtonOn in haldevice.buttons.DeviceElements"
|
||||||
|
value="{{aButtonOn}}">{{aButtonOn.DeviceName}}</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<select name="button-off" id="button-off" ng-model="button_off">
|
||||||
|
<option ng-repeat="aButtonOff in haldevice.buttons.DeviceElements"
|
||||||
|
value="{{aButtonOff}}">{{aButtonOff.DeviceName}}</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<button ng-if="haldevice.haldevicetype != 'Home' && haldevice.haldevicetype != 'HVAC' && haldevice.haldevicetype != 'IrData'" class="btn btn-success" type="submit"
|
||||||
|
ng-click="buildDeviceUrls(haldevice, device_dim_control)">Generate
|
||||||
|
Bridge Device</button>
|
||||||
|
<button ng-if="haldevice.haldevicetype == 'Home'" class="btn btn-success" type="submit"
|
||||||
|
ng-click="buildHALHomeUrls(haldevice)">Home/Away</button>
|
||||||
|
<button ng-if="haldevice.haldevicetype == 'IrData'" class="btn btn-success" type="submit"
|
||||||
|
ng-click="buildButtonUrls(haldevice, button_on, button_off)">Build
|
||||||
|
A Button</button>
|
||||||
|
<ul ng-if="haldevice.haldevicetype == 'HVAC'" class="list-group">
|
||||||
|
<li class="list-group-item">
|
||||||
|
<p>
|
||||||
|
<button class="btn btn-success" type="submit"
|
||||||
|
ng-click="buildHALHeatUrls(haldevice)">Heat</button>
|
||||||
|
<button class="btn btn-success" type="submit"
|
||||||
|
ng-click="buildHALCoolUrls(haldevice)">Cool</button>
|
||||||
|
<button class="btn btn-success" type="submit"
|
||||||
|
ng-click="buildHALAutoUrls(haldevice)">Auto</button>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<button class="btn btn-success" type="submit"
|
||||||
|
ng-click="buildHALOffUrls(haldevice)">Off</button>
|
||||||
|
<button class="btn btn-success" type="submit"
|
||||||
|
ng-click="buildHALFanUrls(haldevice)">Fan</button>
|
||||||
|
</p>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</scrollable-table>
|
||||||
|
<div class="panel-footer">
|
||||||
|
<button class="btn btn-success" type="submit"
|
||||||
|
ng-click="bulkAddDevices(device_dim_control)">Bulk Add
|
||||||
|
({{bulk.devices.length}})</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h2 class="panel-title">
|
||||||
|
Already Configured HAL Devices <a ng-click="toggleButtons()"><span
|
||||||
|
class={{imgButtonsUrl}} aria-hidden="true"></span></a></a>
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<scrollable-table ng-if="buttonsVisible" watch="bridge.haldevices">
|
||||||
|
<table class="table table-bordered table-striped table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Row</th>
|
||||||
|
<th sortable-header col="name">Name</th>
|
||||||
|
<th sortable-header col="category">Category</th>
|
||||||
|
<th sortable-header col="halname">HAL</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tr
|
||||||
|
ng-repeat="device in bridge.devices | unavailableHalDeviceId">
|
||||||
|
<td>{{$index+1}}</td>
|
||||||
|
<td>{{device.name}}</td>
|
||||||
|
<td>{{device.deviceType}}</td>
|
||||||
|
<td>{{device.targetDevice}}</td>
|
||||||
|
<td>
|
||||||
|
<button class="btn btn-danger" type="submit"
|
||||||
|
ng-click="deleteDeviceByMapId(device.mapId, device.mapType)">Delete</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</scrollable-table>
|
||||||
|
</div>
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h2 class="panel-title">Add Bridge Device for a HAL Device</h2>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<form class="form-horizontal">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-xs-12 col-sm-2 control-label" for="device-name">Name
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<div class="col-xs-8 col-sm-7">
|
||||||
|
<input type="text" class="form-control" id="device-name"
|
||||||
|
ng-model="device.name" placeholder="Device Name">
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="col-xs-4 col-sm-2 btn btn-primary"
|
||||||
|
ng-click="addDevice()">Add Bridge Device</button>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="row">
|
||||||
|
<label class="col-xs-12 col-sm-2 control-label" for="device-on-url">On
|
||||||
|
URL </label>
|
||||||
|
|
||||||
|
<div class="col-xs-8 col-sm-7">
|
||||||
|
<textarea rows="3" class="form-control" id="device-on-url"
|
||||||
|
ng-model="device.onUrl" placeholder="URL to turn device on"></textarea>
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-danger" ng-click="clearDevice()">
|
||||||
|
Clear Device</button>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="row">
|
||||||
|
<label class="col-xs-12 col-sm-2 control-label"
|
||||||
|
for="device-dim-url">Dim URL </label>
|
||||||
|
|
||||||
|
<div class="col-xs-8 col-sm-7">
|
||||||
|
<textarea rows="3" class="form-control" id="device-dim-url"
|
||||||
|
ng-model="device.dimUrl" placeholder="URL to dim device"></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="row">
|
||||||
|
<label class="col-xs-12 col-sm-2 control-label"
|
||||||
|
for="device-off-url">Off URL </label>
|
||||||
|
|
||||||
|
<div class="col-xs-8 col-sm-7">
|
||||||
|
<textarea rows="3" class="form-control" id="device-off-url"
|
||||||
|
ng-model="device.offUrl" placeholder="URL to turn device off"></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script type="text/ng-template" id="deleteMapandIdDialog">
|
||||||
|
<div class="ngdialog-message">
|
||||||
|
<h2>Device Map and Id?</h2>
|
||||||
|
<p>{{mapandid.mapType}} with {{mapandid.id}}</p>
|
||||||
|
<p>Are you Sure?</p>
|
||||||
|
</div>
|
||||||
|
<div class="ngdialog-buttons mt">
|
||||||
|
<button type="button" class="ngdialog-button ngdialog-button-error" ng-click="deleteMapandId(mapandid)">Delete</button>
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
@@ -1,100 +1,113 @@
|
|||||||
<ul class="nav nav-pills" role="tablist">
|
<ul class="nav nav-pills" role="tablist">
|
||||||
<li role="presentation"><a href="#">Bridge Devices</a></li>
|
<li role="presentation"><a href="#">Bridge Devices</a></li>
|
||||||
<li role="presentation"><a href="#/system">Bridge Control</a></li>
|
<li role="presentation"><a href="#/system">Bridge Control</a></li>
|
||||||
<li role="presentation"><a href="#/logs">Logs</a></li>
|
<li role="presentation"><a href="#/logs">Logs</a></li>
|
||||||
<li ng-if="bridge.showVera" role="presentation"><a href="#/veradevices">Vera Devices</a></li>
|
<li ng-if="bridge.showVera" role="presentation"><a
|
||||||
<li ng-if="bridge.showVera" role="presentation"><a href="#/verascenes">Vera Scenes</a></li>
|
href="#/veradevices">Vera Devices</a></li>
|
||||||
<li role="presentation" class="active"><a href="#/harmonyactivities">Harmony Activities</a></li>
|
<li ng-if="bridge.showVera" role="presentation"><a
|
||||||
<li role="presentation"><a href="#/harmonydevices">Harmony Devices</a></li>
|
href="#/verascenes">Vera Scenes</a></li>
|
||||||
<li ng-if="bridge.showNest" role="presentation"><a href="#/nest">Nest</a></li>
|
<li role="presentation" class="active"><a
|
||||||
<li role="presentation"><a href="#/editor">Manual Add</a></li>
|
href="#/harmonyactivities">Harmony Activities</a></li>
|
||||||
</ul>
|
<li role="presentation"><a href="#/harmonydevices">Harmony
|
||||||
|
Devices</a></li>
|
||||||
|
<li ng-if="bridge.showNest" role="presentation"><a href="#/nest">Nest</a></li>
|
||||||
|
<li ng-if="bridge.showHue" role="presentation"><a
|
||||||
|
href="#/huedevices">Hue Devices</a></li>
|
||||||
|
<li ng-if="bridge.showHal" role="presentation"><a
|
||||||
|
href="#/haldevices">HAL Devices</a></li>
|
||||||
|
<li role="presentation"><a href="#/editor">Manual Add</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<div class="panel panel-default bridgeServer" ng-if="!bridge.error">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h2 class="panel-title">Harmony Activity List</h2>
|
<h2 class="panel-title">Harmony Activity List</h2>
|
||||||
</div>
|
</div>
|
||||||
<ul class="list-group">
|
<div class="panel-body">
|
||||||
<li class="list-group-item">
|
<p class="text-muted">For any Harmony Activity, use the action
|
||||||
<p class="text-muted">For any Harmony Activity, use the action buttons to generate the device addition information below automatically.
|
buttons to generate the device addition information below
|
||||||
Then you can modify the name to anything you want that will be the keyword for Alexa. Click the 'Add Bridge Device' to finish that selection setup.
|
automatically. Then you can modify the name to anything you want that
|
||||||
The 'Already Configured Activities' list below will show what is already setup for your Harmony Hubs.</p>
|
will be the keyword for Alexa. Click the 'Add Bridge Device' to
|
||||||
|
finish that selection setup. The 'Already Configured Activities' list
|
||||||
<scrollable-table watch="bridge.harmonyactivities">
|
below will show what is already setup for your Harmony Hubs.</p>
|
||||||
<table class="table table-bordered table-striped table-hover">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Row</th>
|
|
||||||
<th sortable-header col="name">Name</th>
|
|
||||||
<th sortable-header col="id">Id</th>
|
|
||||||
<th sortable-header col="hub">Hub</th>
|
|
||||||
<th>Actions</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tr ng-repeat="harmonyactivity in bridge.harmonyactivities | availableHarmonyActivityId">
|
|
||||||
<td>{{$index+1}}</td>
|
|
||||||
<td>{{harmonyactivity.activity.label}}</td>
|
|
||||||
<td>{{harmonyactivity.activity.id}}</td>
|
|
||||||
<td>{{harmonyactivity.hub}}</td>
|
|
||||||
<td>
|
|
||||||
<button class="btn btn-success" type="submit"
|
|
||||||
ng-click="buildActivityUrls(harmonyactivity)">Generate
|
|
||||||
Activity URLs</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</scrollable-table>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div class="panel-heading">
|
|
||||||
<h2 class="panel-title">Already Configured Activities <a ng-click="toggleButtons()"><span class={{imgButtonsUrl}} aria-hidden="true"></span></a></h2>
|
|
||||||
</div>
|
</div>
|
||||||
<ul ng-if="buttonsVisible" class="list-group">
|
|
||||||
<li class="list-group-item">
|
<scrollable-table watch="bridge.harmonyactivities">
|
||||||
<scrollable-table watch="bridge.harmonyactivities">
|
<table class="table table-bordered table-striped table-hover">
|
||||||
<table class="table table-bordered table-striped table-hover">
|
<thead>
|
||||||
<thead>
|
<tr>
|
||||||
<tr>
|
<th>Row</th>
|
||||||
<th>Row</th>
|
<th sortable-header col="name">Name</th>
|
||||||
<th sortable-header col="name">Name</th>
|
<th sortable-header col="id">Id</th>
|
||||||
<th sortable-header col="id">Id</th>
|
<th sortable-header col="hub">Hub</th>
|
||||||
<th sortable-header col="hub">Hub</th>
|
<th>Actions</th>
|
||||||
<th>Actions</th>
|
</tr>
|
||||||
</tr>
|
</thead>
|
||||||
</thead>
|
<tr
|
||||||
<tr ng-repeat="harmonyactivity in bridge.harmonyactivities | unavailableHarmonyActivityId">
|
ng-repeat="harmonyactivity in bridge.harmonyactivities | availableHarmonyActivityId">
|
||||||
<td>{{$index+1}}</td>
|
<td>{{$index+1}}</td>
|
||||||
<td>{{harmonyactivity.activity.label}}</td>
|
<td>{{harmonyactivity.activity.label}}</td>
|
||||||
<td>{{harmonyactivity.activity.id}}</td>
|
<td>{{harmonyactivity.activity.id}}</td>
|
||||||
<td>{{harmonyactivity.hub}}</td>
|
<td>{{harmonyactivity.hub}}</td>
|
||||||
<td><button class="btn btn-danger" type="submit"
|
<td>
|
||||||
ng-click="deleteDeviceByMapId(harmonyactivity.activity.id, 'harmonyActivity')">Delete</button></td>
|
<button class="btn btn-success" type="submit"
|
||||||
</tr>
|
ng-click="buildActivityUrls(harmonyactivity)">Generate
|
||||||
</table>
|
Bridge Device</button>
|
||||||
</scrollable-table>
|
</td>
|
||||||
</li>
|
</tr>
|
||||||
</ul>
|
</table>
|
||||||
|
</scrollable-table>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel panel-default bridgeServer" ng-if="!bridge.error">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h2 class="panel-title">Add a Bridge Device for a Harmony Activity</h2>
|
<h2 class="panel-title">
|
||||||
|
Already Configured Activities <a ng-click="toggleButtons()"><span
|
||||||
|
class={{imgButtonsUrl}} aria-hidden="true"></span></a>
|
||||||
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<ul class="list-group">
|
<scrollable-table ng-if="buttonsVisible"
|
||||||
<li class="list-group-item">
|
watch="bridge.harmonyactivities">
|
||||||
<form class="form-horizontal">
|
<table class="table table-bordered table-striped table-hover">
|
||||||
<div class="form-group">
|
<thead>
|
||||||
<label class="col-xs-12 col-sm-2 control-label" for="device-name">Name
|
<tr>
|
||||||
</label>
|
<th>Row</th>
|
||||||
|
<th sortable-header col="name">Name</th>
|
||||||
|
<th sortable-header col="id">Id</th>
|
||||||
|
<th sortable-header col="hub">Hub</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tr
|
||||||
|
ng-repeat="harmonyactivity in bridge.harmonyactivities | unavailableHarmonyActivityId">
|
||||||
|
<td>{{$index+1}}</td>
|
||||||
|
<td>{{harmonyactivity.activity.label}}</td>
|
||||||
|
<td>{{harmonyactivity.activity.id}}</td>
|
||||||
|
<td>{{harmonyactivity.hub}}</td>
|
||||||
|
<td><button class="btn btn-danger" type="submit"
|
||||||
|
ng-click="deleteDeviceByMapId(harmonyactivity.activity.id, 'harmonyActivity')">Delete</button></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</scrollable-table>
|
||||||
|
</div>
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h2 class="panel-title">Add a Bridge Device for a Harmony
|
||||||
|
Activity</h2>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<form class="form-horizontal">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-xs-12 col-sm-2 control-label" for="device-name">Name
|
||||||
|
</label>
|
||||||
|
|
||||||
<div class="col-xs-8 col-sm-7">
|
<div class="col-xs-8 col-sm-7">
|
||||||
<input type="text" class="form-control" id="device-name"
|
<input type="text" class="form-control" id="device-name"
|
||||||
ng-model="device.name" placeholder="Device Name">
|
ng-model="device.name" placeholder="Device Name">
|
||||||
</div>
|
|
||||||
<button type="submit" class="col-xs-4 col-sm-2 btn btn-primary" ng-click="addDevice()">
|
|
||||||
Add Bridge Device</button>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<button type="submit" class="col-xs-4 col-sm-2 btn btn-primary"
|
||||||
<div class="row">
|
ng-click="addDevice()">Add Bridge Device</button>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="row">
|
||||||
<label class="col-xs-12 col-sm-2 control-label" for="device-on-url">On
|
<label class="col-xs-12 col-sm-2 control-label" for="device-on-url">On
|
||||||
URL </label>
|
URL </label>
|
||||||
|
|
||||||
@@ -104,10 +117,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<button class="btn btn-danger" ng-click="clearDevice()">
|
<button class="btn btn-danger" ng-click="clearDevice()">
|
||||||
Clear Device</button>
|
Clear Device</button>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
</div>
|
||||||
<div class="row">
|
<div class="form-group">
|
||||||
|
<div class="row">
|
||||||
<label class="col-xs-12 col-sm-2 control-label"
|
<label class="col-xs-12 col-sm-2 control-label"
|
||||||
for="device-off-url">Off URL </label>
|
for="device-off-url">Off URL </label>
|
||||||
|
|
||||||
@@ -115,9 +128,18 @@
|
|||||||
<textarea rows="3" class="form-control" id="device-off-url"
|
<textarea rows="3" class="form-control" id="device-off-url"
|
||||||
ng-model="device.offUrl" placeholder="URL to turn device off"></textarea>
|
ng-model="device.offUrl" placeholder="URL to turn device off"></textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</div>
|
||||||
</li>
|
</form>
|
||||||
</ul>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<script type="text/ng-template" id="deleteMapandIdDialog">
|
||||||
|
<div class="ngdialog-message">
|
||||||
|
<h2>Device Map and Id?</h2>
|
||||||
|
<p>{{mapandid.mapType}} with {{mapandid.id}}</p>
|
||||||
|
<p>Are you Sure?</p>
|
||||||
|
</div>
|
||||||
|
<div class="ngdialog-buttons mt">
|
||||||
|
<button type="button" class="ngdialog-button ngdialog-button-error" ng-click="deleteMapandId(mapandid)">Delete</button>
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
@@ -1,120 +1,137 @@
|
|||||||
<ul class="nav nav-pills" role="tablist">
|
<ul class="nav nav-pills" role="tablist">
|
||||||
<li role="presentation"><a href="#">Bridge Devices</a></li>
|
<li role="presentation"><a href="#">Bridge Devices</a></li>
|
||||||
<li role="presentation"><a href="#/system">Bridge Control</a></li>
|
<li role="presentation"><a href="#/system">Bridge Control</a></li>
|
||||||
<li role="presentation"><a href="#/logs">Logs</a></li>
|
<li role="presentation"><a href="#/logs">Logs</a></li>
|
||||||
<li ng-if="bridge.showVera" role="presentation"><a href="#/veradevices">Vera Devices</a></li>
|
<li ng-if="bridge.showVera" role="presentation"><a
|
||||||
<li ng-if="bridge.showVera" role="presentation"><a href="#/verascenes">Vera Scenes</a></li>
|
href="#/veradevices">Vera Devices</a></li>
|
||||||
<li role="presentation"><a href="#/harmonyactivities">Harmony Activities</a></li>
|
<li ng-if="bridge.showVera" role="presentation"><a
|
||||||
<li role="presentation" class="active"><a href="#/harmonydevices">Harmony Devices</a></li>
|
href="#/verascenes">Vera Scenes</a></li>
|
||||||
<li ng-if="bridge.showNest" role="presentation"><a href="#/nest">Nest</a></li>
|
<li role="presentation"><a href="#/harmonyactivities">Harmony
|
||||||
<li role="presentation"><a href="#/editor">Manual Add</a></li>
|
Activities</a></li>
|
||||||
</ul>
|
<li role="presentation" class="active"><a href="#/harmonydevices">Harmony
|
||||||
|
Devices</a></li>
|
||||||
|
<li ng-if="bridge.showNest" role="presentation"><a href="#/nest">Nest</a></li>
|
||||||
|
<li ng-if="bridge.showHue" role="presentation"><a
|
||||||
|
href="#/huedevices">Hue Devices</a></li>
|
||||||
|
<li ng-if="bridge.showHal" role="presentation"><a
|
||||||
|
href="#/haldevices">HAL Devices</a></li>
|
||||||
|
<li role="presentation"><a href="#/editor">Manual Add</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<div class="panel panel-default bridgeServer" ng-if="!bridge.error">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h2 class="panel-title">Harmony Device List</h2>
|
<h2 class="panel-title">Harmony Device List</h2>
|
||||||
</div>
|
</div>
|
||||||
<ul class="list-group">
|
<div class="panel-body">
|
||||||
<li class="list-group-item">
|
<p class="text-muted">For any Harmony Device and Buttons, use the
|
||||||
<p class="text-muted">For any Harmony Device and Buttons, use the build button to generate the configuration for this bridge device. You can add button presses by
|
build button to generate the configuration for this bridge device.
|
||||||
selecting yoru devic and buttons and then selecting the Build Button. This will allow multiple button presses to be built for a given device.
|
You can add button presses by selecting yoru devic and buttons and
|
||||||
Then you can modify the name to anything you want that will be the keyword for Alexa. Click the 'Add Bridge Device' to finish that selection setup.
|
then selecting the Build Button. This will allow multiple button
|
||||||
The 'Already Configured Harmony Buttons' list below will show what is already setup for your Harmony Hubs.</p>
|
presses to be built for a given device. Then you can modify the name
|
||||||
|
to anything you want that will be the keyword for Alexa. Click the
|
||||||
<scrollable-table watch="bridge.harmonydevices">
|
'Add Bridge Device' to finish that selection setup. The 'Already
|
||||||
<table class="table table-bordered table-striped table-hover">
|
Configured Harmony Buttons' list below will show what is already
|
||||||
<thead>
|
setup for your Harmony Hubs.</p>
|
||||||
<tr>
|
|
||||||
<th>Row</th>
|
|
||||||
<th sortable-header col="name">Name</th>
|
|
||||||
<th sortable-header col="id">Id</th>
|
|
||||||
<th sortable-header col="hub">Hub</th>
|
|
||||||
<th>On Button</th>
|
|
||||||
<th>Off Button</th>
|
|
||||||
<th>Actions</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tr ng-repeat="harmonydevice in bridge.harmonydevices">
|
|
||||||
<td>{{$index+1}}</td>
|
|
||||||
<td>{{harmonydevice.device.label}}</td>
|
|
||||||
<td>{{harmonydevice.device.id}}</td>
|
|
||||||
<td>{{harmonydevice.hub}}</td>
|
|
||||||
<td>
|
|
||||||
<select name="device-ctrlon" id="device-ctrlon" ng-model="devicectrlon">
|
|
||||||
<optgroup ng-repeat="ctrlon in harmonydevice.device.controlGroup" label="{{ctrlon.name}}">
|
|
||||||
<option ng-repeat="funcon in ctrlon.function" value="{{funcon.action}}">{{funcon.label}}</option>
|
|
||||||
</optgroup >
|
|
||||||
</select>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<select name="device-ctrloff" id="device-ctrloff" ng-model="devicectrloff">
|
|
||||||
<optgroup ng-repeat="ctrloff in harmonydevice.device.controlGroup" label="{{ctrloff.name}}">
|
|
||||||
<option ng-repeat="funcoff in ctrloff.function" value="{{funcoff.action}}">{{funcoff.label}}</option>
|
|
||||||
</optgroup >
|
|
||||||
</select>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<button class="btn btn-success" type="submit"
|
|
||||||
ng-click="buildButtonUrls(harmonydevice, devicectrlon, devicectrloff)">Build A Button</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</scrollable-table>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div class="panel-heading">
|
|
||||||
<h2 class="panel-title">Already Configured Harmony Buttons <a ng-click="toggleButtons()"><span class={{imgButtonsUrl}} aria-hidden="true"></span></a></h2>
|
|
||||||
</div>
|
</div>
|
||||||
<ul ng-if="buttonsVisible" class="list-group">
|
|
||||||
<li class="list-group-item">
|
<scrollable-table watch="bridge.harmonydevices">
|
||||||
<scrollable-table watch="bridge.harmonydevices">
|
<table class="table table-bordered table-striped table-hover">
|
||||||
<table class="table table-bordered table-striped table-hover">
|
<thead>
|
||||||
<thead>
|
<tr>
|
||||||
<tr>
|
<th>Row</th>
|
||||||
<th>Row</th>
|
<th sortable-header col="name">Name</th>
|
||||||
<th sortable-header col="name">Name</th>
|
<th sortable-header col="id">Id</th>
|
||||||
<th sortable-header col="id">Device Id</th>
|
<th sortable-header col="hub">Hub</th>
|
||||||
<th sortable-header col="targetDevice">Hub</th>
|
<th>On Button</th>
|
||||||
<th>Harmony Device-Button On-Button Off</th>
|
<th>Off Button</th>
|
||||||
<th>Actions</th>
|
<th>Actions</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tr ng-repeat="device in bridge.devices | configuredButtons | orderBy:predicate:reverse">
|
<tr ng-repeat="harmonydevice in bridge.harmonydevices">
|
||||||
<td>{{$index+1}}</td>
|
<td>{{$index+1}}</td>
|
||||||
<td>{{device.name}}</td>
|
<td>{{harmonydevice.device.label}}</td>
|
||||||
<td>{{device.id}}</td>
|
<td>{{harmonydevice.device.id}}</td>
|
||||||
<td>{{device.targetDevice}}</td>
|
<td>{{harmonydevice.hub}}</td>
|
||||||
<td>{{device.mapId}}</td>
|
<td><select name="device-ctrlon" id="device-ctrlon"
|
||||||
<td>
|
ng-model="devicectrlon">
|
||||||
<button class="btn btn-danger" type="submit"
|
<optgroup ng-repeat="ctrlon in harmonydevice.device.controlGroup"
|
||||||
ng-click="deleteDeviceByMapId(device.mapId, device.mapType)">Delete</button>
|
label="{{ctrlon.name}}">
|
||||||
</td>
|
<option ng-repeat="funcon in ctrlon.function"
|
||||||
</tr>
|
value="{{funcon.action}}">{{funcon.label}}</option>
|
||||||
</table>
|
</optgroup>
|
||||||
</scrollable-table>
|
</select></td>
|
||||||
</li>
|
<td><select name="device-ctrloff" id="device-ctrloff"
|
||||||
|
ng-model="devicectrloff">
|
||||||
|
<optgroup ng-repeat="ctrloff in harmonydevice.device.controlGroup"
|
||||||
|
label="{{ctrloff.name}}">
|
||||||
|
<option ng-repeat="funcoff in ctrloff.function"
|
||||||
|
value="{{funcoff.action}}">{{funcoff.label}}</option>
|
||||||
|
</optgroup>
|
||||||
|
</select></td>
|
||||||
|
<td>
|
||||||
|
<button class="btn btn-success" type="submit"
|
||||||
|
ng-click="buildButtonUrls(harmonydevice, devicectrlon, devicectrloff)">Build
|
||||||
|
A Button</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</scrollable-table>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel panel-default bridgeServer" ng-if="!bridge.error">
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h2 class="panel-title">
|
||||||
|
Already Configured Harmony Buttons <a ng-click="toggleButtons()"><span
|
||||||
|
class={{imgButtonsUrl}} aria-hidden="true"></span></a>
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<scrollable-table ng-if="buttonsVisible" watch="bridge.harmonydevices">
|
||||||
|
<table class="table table-bordered table-striped table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Row</th>
|
||||||
|
<th sortable-header col="name">Name</th>
|
||||||
|
<th sortable-header col="id">Device Id</th>
|
||||||
|
<th sortable-header col="targetDevice">Hub</th>
|
||||||
|
<th>Harmony Device-Button On-Button Off</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tr
|
||||||
|
ng-repeat="device in bridge.devices | configuredButtons | orderBy:predicate:reverse">
|
||||||
|
<td>{{$index+1}}</td>
|
||||||
|
<td>{{device.name}}</td>
|
||||||
|
<td>{{device.id}}</td>
|
||||||
|
<td>{{device.targetDevice}}</td>
|
||||||
|
<td>{{device.mapId}}</td>
|
||||||
|
<td>
|
||||||
|
<button class="btn btn-danger" type="submit"
|
||||||
|
ng-click="deleteDeviceByMapId(device.mapId, device.mapType)">Delete</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</scrollable-table>
|
||||||
|
</div>
|
||||||
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h2 class="panel-title">Add a Bridge Device for Harmony Buttons</h2>
|
<h2 class="panel-title">Add a Bridge Device for Harmony Buttons</h2>
|
||||||
</div>
|
</div>
|
||||||
<ul class="list-group">
|
<div class="panel-body">
|
||||||
<li class="list-group-item">
|
<form class="form-horizontal">
|
||||||
<form class="form-horizontal">
|
<div class="form-group">
|
||||||
<div class="form-group">
|
<label class="col-xs-12 col-sm-2 control-label" for="device-name">Name
|
||||||
<label class="col-xs-12 col-sm-2 control-label" for="device-name">Name
|
</label>
|
||||||
</label>
|
|
||||||
|
|
||||||
<div class="col-xs-8 col-sm-7">
|
<div class="col-xs-8 col-sm-7">
|
||||||
<input type="text" class="form-control" id="device-name"
|
<input type="text" class="form-control" id="device-name"
|
||||||
ng-model="device.name" placeholder="Device Name">
|
ng-model="device.name" placeholder="Device Name">
|
||||||
</div>
|
|
||||||
<button type="submit" class="col-xs-4 col-sm-2 btn btn-primary" ng-click="addDevice()">
|
|
||||||
Add Bridge Device</button>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<button type="submit" class="col-xs-4 col-sm-2 btn btn-primary"
|
||||||
<div class="row">
|
ng-click="addDevice()">Add Bridge Device</button>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="row">
|
||||||
<label class="col-xs-12 col-sm-2 control-label" for="device-on-url">On
|
<label class="col-xs-12 col-sm-2 control-label" for="device-on-url">On
|
||||||
URL </label>
|
URL </label>
|
||||||
|
|
||||||
@@ -124,10 +141,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<button class="btn btn-danger" ng-click="clearDevice()">
|
<button class="btn btn-danger" ng-click="clearDevice()">
|
||||||
Clear Device</button>
|
Clear Device</button>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
</div>
|
||||||
<div class="row">
|
<div class="form-group">
|
||||||
|
<div class="row">
|
||||||
<label class="col-xs-12 col-sm-2 control-label"
|
<label class="col-xs-12 col-sm-2 control-label"
|
||||||
for="device-off-url">Off URL </label>
|
for="device-off-url">Off URL </label>
|
||||||
|
|
||||||
@@ -135,9 +152,18 @@
|
|||||||
<textarea rows="3" class="form-control" id="device-off-url"
|
<textarea rows="3" class="form-control" id="device-off-url"
|
||||||
ng-model="device.offUrl" placeholder="URL to turn device off"></textarea>
|
ng-model="device.offUrl" placeholder="URL to turn device off"></textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</div>
|
||||||
</li>
|
</form>
|
||||||
</ul>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<script type="text/ng-template" id="deleteMapandIdDialog">
|
||||||
|
<div class="ngdialog-message">
|
||||||
|
<h2>Device Map and Id?</h2>
|
||||||
|
<p>{{mapandid.mapType}} with {{mapandid.id}}</p>
|
||||||
|
<p>Are you Sure?</p>
|
||||||
|
</div>
|
||||||
|
<div class="ngdialog-buttons mt">
|
||||||
|
<button type="button" class="ngdialog-button ngdialog-button-error" ng-click="deleteMapandId(mapandid)">Delete</button>
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
148
src/main/resources/public/views/huedevice.html
Normal file
148
src/main/resources/public/views/huedevice.html
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
<ul class="nav nav-pills" role="tablist">
|
||||||
|
<li role="presentation"><a href="#">Bridge Devices</a></li>
|
||||||
|
<li role="presentation"><a href="#/system">Bridge Control</a></li>
|
||||||
|
<li role="presentation"><a href="#/logs">Logs</a></li>
|
||||||
|
<li ng-if="bridge.showVera" role="presentation"><a
|
||||||
|
href="#/veradevices">Vera Devices</a></li>
|
||||||
|
<li ng-if="bridge.showVera" role="presentation"><a
|
||||||
|
href="#/verascenes">Vera Scenes</a></li>
|
||||||
|
<li ng-if="bridge.showHarmony" role="presentation"><a
|
||||||
|
href="#/harmonyactivities">Harmony Activities</a></li>
|
||||||
|
<li ng-if="bridge.showHarmony" role="presentation"><a
|
||||||
|
href="#/harmonydevices">Harmony Devices</a></li>
|
||||||
|
<li ng-if="bridge.showNest" role="presentation"><a href="#/nest">Nest</a></li>
|
||||||
|
<li role="presentation" class="active"><a href="#/huedevices">Hue
|
||||||
|
Devices</a></li>
|
||||||
|
<li ng-if="bridge.showHal" role="presentation"><a
|
||||||
|
href="#/haldevices">HAL Devices</a></li>
|
||||||
|
<li role="presentation"><a href="#/editor">Manual Add</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h2 class="panel-title">Hue Device List
|
||||||
|
({{bridge.huedevices.length}})</h2>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<p class="text-muted">For any Hue Device, use the action buttons
|
||||||
|
to generate the device addition information below automatically. Then
|
||||||
|
you can modify the name to anything you want that will be the keyword
|
||||||
|
for Alexa. 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.</p>
|
||||||
|
<p>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 and off or dim and off if selected with the
|
||||||
|
name of the device from the Hue.</p>
|
||||||
|
</div>
|
||||||
|
<scrollable-table watch="bridge.huedevices">
|
||||||
|
<table class="table table-bordered table-striped table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Row</th>
|
||||||
|
<th sortable-header col="name"><span><input type="checkbox" name="selectAll"
|
||||||
|
value="{{selectAll}}"
|
||||||
|
ng-checked="selectAll"
|
||||||
|
ng-click="toggleSelectAll()"> Name</span></th>
|
||||||
|
<th sortable-header col="id">Id</th>
|
||||||
|
<th sortable-header col="huename">Hue</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tr ng-repeat="huedevice in bridge.huedevices | availableHueDeviceId">
|
||||||
|
<td>{{$index+1}}</td>
|
||||||
|
<td><input type="checkbox" name="bulk.devices[]"
|
||||||
|
value="{{huedevice.device.uniqueid}}"
|
||||||
|
ng-checked="bulk.devices.indexOf(huedevice.device.uniqueid) > -1"
|
||||||
|
ng-click="toggleSelection(huedevice.device.uniqueid)">
|
||||||
|
{{huedevice.device.name}}</td>
|
||||||
|
<td>{{huedevice.device.uniqueid}}</td>
|
||||||
|
<td>{{huedevice.huename}}</td>
|
||||||
|
<td>
|
||||||
|
<button class="btn btn-success" type="submit"
|
||||||
|
ng-click="buildDeviceUrls(huedevice)">Generate Bridge
|
||||||
|
Device</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</scrollable-table>
|
||||||
|
<div class="panel-footer">
|
||||||
|
<button class="btn btn-success" type="submit"
|
||||||
|
ng-click="bulkAddDevices()">Bulk Add
|
||||||
|
({{bulk.devices.length}})</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h2 class="panel-title">
|
||||||
|
Already Configured Hue Devices <a ng-click="toggleButtons()"><span
|
||||||
|
class={{imgButtonsUrl}} aria-hidden="true"></span></a></a>
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<scrollable-table ng-if="buttonsVisible" watch="bridge.huedevices">
|
||||||
|
<table class="table table-bordered table-striped table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Row</th>
|
||||||
|
<th sortable-header col="name">Name</th>
|
||||||
|
<th sortable-header col="id">Id</th>
|
||||||
|
<th sortable-header col="huename">hue</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tr
|
||||||
|
ng-repeat="huedevice in bridge.huedevices | unavailableHueDeviceId">
|
||||||
|
<td>{{$index+1}}</td>
|
||||||
|
<td>{{huedevice.device.name}}</td>
|
||||||
|
<td>{{huedevice.device.uniqueid}}</td>
|
||||||
|
<td>{{huedevice.huename}}</td>
|
||||||
|
<td>
|
||||||
|
<button class="btn btn-danger" type="submit"
|
||||||
|
ng-click="deleteDeviceByMapId(huedevice.device.uniqueid, 'hueDevice')">Delete</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</scrollable-table>
|
||||||
|
</div>
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h2 class="panel-title">Add Bridge Device for a Hue Device</h2>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<form class="form-horizontal">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-xs-12 col-sm-2 control-label" for="device-name">Name
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<div class="col-xs-8 col-sm-7">
|
||||||
|
<input type="text" class="form-control" id="device-name"
|
||||||
|
ng-model="device.name" placeholder="Device Name">
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="col-xs-4 col-sm-2 btn btn-primary"
|
||||||
|
ng-click="addDevice()">Add Bridge Device</button>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="row">
|
||||||
|
<label class="col-xs-12 col-sm-2 control-label" for="device-on-url">On
|
||||||
|
URL </label>
|
||||||
|
|
||||||
|
<div class="col-xs-8 col-sm-7">
|
||||||
|
<textarea rows="3" class="form-control" id="device-on-url"
|
||||||
|
ng-model="device.onUrl" placeholder="URL to turn device on"></textarea>
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-danger" ng-click="clearDevice()">
|
||||||
|
Clear Device</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script type="text/ng-template" id="deleteMapandIdDialog">
|
||||||
|
<div class="ngdialog-message">
|
||||||
|
<h2>Device Map and Id?</h2>
|
||||||
|
<p>{{mapandid.mapType}} with {{mapandid.id}}</p>
|
||||||
|
<p>Are you Sure?</p>
|
||||||
|
</div>
|
||||||
|
<div class="ngdialog-buttons mt">
|
||||||
|
<button type="button" class="ngdialog-button ngdialog-button-error" ng-click="deleteMapandId(mapandid)">Delete</button>
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
@@ -1,75 +1,85 @@
|
|||||||
<ul class="nav nav-pills" role="tablist">
|
<ul class="nav nav-pills" role="tablist">
|
||||||
<li role="presentation"><a href="#">Bridge Devices</a></li>
|
<li role="presentation"><a href="#">Bridge Devices</a></li>
|
||||||
<li role="presentation"><a href="#/system">Bridge Control</a></li>
|
<li role="presentation"><a href="#/system">Bridge Control</a></li>
|
||||||
<li role="presentation" class="active"><a href="#/logs">Logs</a></li>
|
<li role="presentation" class="active"><a href="#/logs">Logs</a></li>
|
||||||
<li ng-if="bridge.showVera" role="presentation"><a href="#/veradevices">Vera Devices</a></li>
|
<li ng-if="bridge.showVera" role="presentation"><a
|
||||||
<li ng-if="bridge.showVera" role="presentation"><a href="#/verascenes">Vera Scenes</a></li>
|
href="#/veradevices">Vera Devices</a></li>
|
||||||
<li ng-if="bridge.showHarmony" role="presentation"><a href="#/harmonyactivities">Harmony Activities</a></li>
|
<li ng-if="bridge.showVera" role="presentation"><a
|
||||||
<li ng-if="bridge.showHarmony" role="presentation"><a href="#/harmonydevices">Harmony Devices</a></li>
|
href="#/verascenes">Vera Scenes</a></li>
|
||||||
<li ng-if="bridge.showNest" role="presentation"><a href="#/nest">Nest</a></li>
|
<li ng-if="bridge.showHarmony" role="presentation"><a
|
||||||
<li role="presentation"><a href="#/editor">Manual Add</a></li>
|
href="#/harmonyactivities">Harmony Activities</a></li>
|
||||||
</ul>
|
<li ng-if="bridge.showHarmony" role="presentation"><a
|
||||||
|
href="#/harmonydevices">Harmony Devices</a></li>
|
||||||
|
<li ng-if="bridge.showNest" role="presentation"><a href="#/nest">Nest</a></li>
|
||||||
|
<li ng-if="bridge.showHue" role="presentation"><a
|
||||||
|
href="#/huedevices">Hue Devices</a></li>
|
||||||
|
<li ng-if="bridge.showHal" role="presentation"><a
|
||||||
|
href="#/haldevices">HAL Devices</a></li>
|
||||||
|
<li role="presentation"><a href="#/editor">Manual Add</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<div class="panel panel-default bridgeServer">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h1 class="panel-title">Log Messages</h1>
|
<h1 class="panel-title">Log Messages</h1>
|
||||||
</div>
|
|
||||||
<div class="panel-body">
|
|
||||||
<p>
|
|
||||||
<button class="btn btn-primary" type="submit"
|
|
||||||
ng-click="updateLogs()">Update Log</button>
|
|
||||||
</p>
|
|
||||||
<scrollable-table watch="bridge.logMsgs">
|
|
||||||
<table class="table table-striped table-bordered table-hover">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th sortable-header col="time">Time</th>
|
|
||||||
<th sortable-header col="level">Level</th>
|
|
||||||
<th sortable-header col="message">Message</th>
|
|
||||||
<th sortable-header col="component">Component</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tr ng-repeat="logMessage in bridge.logMsgs">
|
|
||||||
<td>{{logMessage.time}}</td>
|
|
||||||
<td>{{logMessage.level}}</td>
|
|
||||||
<td>{{logMessage.message}}</td>
|
|
||||||
<td>{{logMessage.component}}</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</scrollable-table>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="panel panel-default logconfig">
|
<div class="panel-body">
|
||||||
<div class="panel-heading">
|
<p>
|
||||||
<h1 class="panel-title">Logging Configuration <a ng-click="toggle()"><span class={{imgUrl}} aria-hidden="true"></a></h1>
|
<button class="btn btn-primary" type="submit" ng-click="updateLogs()">Update
|
||||||
</div>
|
Log</button>
|
||||||
<div ng-if="visible" class="animate-if" class="panel-body">
|
</p>
|
||||||
<p>
|
|
||||||
<button class="btn btn-primary" type="submit"
|
|
||||||
ng-click="updateLoggers()">Update Log Levels</button>
|
|
||||||
Show All Loggers <input type="checkbox" ng-model="bridge.logShowAll"
|
|
||||||
ng-change="reloadLoggers()" ng-true-value=true ng-false-value=false> {{bridge.logShowAll}}
|
|
||||||
</p>
|
|
||||||
<scrollable-table watch="bridge.loggerInfo">
|
|
||||||
<table class="table table-bordered table-striped table-hover">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th sortable-header col="logLevel">Log Level</th>
|
|
||||||
<th sortable-header col="loggerName">Component</th>
|
|
||||||
<th>New Log Level</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tr ng-repeat="logInfo in bridge.loggerInfo">
|
|
||||||
<td>{{logInfo.logLevel.substr(0,logInfo.logLevel.indexOf("_"))}}</td>
|
|
||||||
<td>{{logInfo.loggerName}}</td>
|
|
||||||
<td>
|
|
||||||
<select name="new-log-level" id="new-log-level" ng-change="addToUpdate(logInfo)" ng-model="logInfo.newLogLevel">
|
|
||||||
<option ng-repeat="alevel in levels" value="{{alevel}}">{{alevel.substr(0,alevel.indexOf("_"))}}</option>
|
|
||||||
</select>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</scrollable-table>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<scrollable-table watch="bridge.logMsgs">
|
||||||
|
<table class="table table-striped table-bordered table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th sortable-header col="time">Time</th>
|
||||||
|
<th sortable-header col="level">Level</th>
|
||||||
|
<th sortable-header col="message">Message</th>
|
||||||
|
<th sortable-header col="component">Component</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tr ng-repeat="logMessage in bridge.logMsgs">
|
||||||
|
<td>{{logMessage.time}}</td>
|
||||||
|
<td>{{logMessage.level}}</td>
|
||||||
|
<td>{{logMessage.message}}</td>
|
||||||
|
<td>{{logMessage.component}}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</scrollable-table>
|
||||||
|
</div>
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h1 class="panel-title">
|
||||||
|
Logging Configuration <a ng-click="toggle()"><span
|
||||||
|
class={{imgUrl}} aria-hidden="true"></a>
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<div ng-if="visible" class="animate-if" class="panel-body">
|
||||||
|
<p>
|
||||||
|
<button class="btn btn-primary" type="submit"
|
||||||
|
ng-click="updateLoggers()">Update Log Levels</button>
|
||||||
|
Show All Loggers <input type="checkbox" ng-model="bridge.logShowAll"
|
||||||
|
ng-change="reloadLoggers()" ng-true-value=true ng-false-value=false>
|
||||||
|
{{bridge.logShowAll}}
|
||||||
|
</p>
|
||||||
|
<scrollable-table watch="bridge.loggerInfo">
|
||||||
|
<table class="table table-bordered table-striped table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th sortable-header col="logLevel">Log Level</th>
|
||||||
|
<th sortable-header col="loggerName">Component</th>
|
||||||
|
<th>New Log Level</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tr ng-repeat="logInfo in bridge.loggerInfo">
|
||||||
|
<td>{{logInfo.logLevel.substr(0,logInfo.logLevel.indexOf("_"))}}</td>
|
||||||
|
<td>{{logInfo.loggerName}}</td>
|
||||||
|
<td><select name="new-log-level" id="new-log-level"
|
||||||
|
ng-change="addToUpdate(logInfo)" ng-model="logInfo.newLogLevel">
|
||||||
|
<option ng-repeat="alevel in levels" value="{{alevel}}">{{alevel.substr(0,alevel.indexOf("_"))}}</option>
|
||||||
|
</select></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</scrollable-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -1,121 +1,132 @@
|
|||||||
<ul class="nav nav-pills" role="tablist">
|
<ul class="nav nav-pills" role="tablist">
|
||||||
<li role="presentation"><a href="#">Bridge Devices</a></li>
|
<li role="presentation"><a href="#">Bridge Devices</a></li>
|
||||||
<li role="presentation"><a href="#/system">Bridge Control</a></li>
|
<li role="presentation"><a href="#/system">Bridge Control</a></li>
|
||||||
<li role="presentation"><a href="#/logs">Logs</a></li>
|
<li role="presentation"><a href="#/logs">Logs</a></li>
|
||||||
<li ng-if="bridge.showVera" role="presentation"><a href="#/veradevices">Vera Devices</a></li>
|
<li ng-if="bridge.showVera" role="presentation"><a
|
||||||
<li ng-if="bridge.showVera" role="presentation"><a href="#/verascenes">Vera Scenes</a></li>
|
href="#/veradevices">Vera Devices</a></li>
|
||||||
<li ng-if="bridge.showHarmony" role="presentation"><a href="#/harmonyactivities">Harmony Activities</a></li>
|
<li ng-if="bridge.showVera" role="presentation"><a
|
||||||
<li ng-if="bridge.showHarmony" role="presentation"><a href="#/harmonydevices">Harmony Devices</a></li>
|
href="#/verascenes">Vera Scenes</a></li>
|
||||||
<li role="presentation" class="active"><a href="#/nest">Nest</a></li>
|
<li ng-if="bridge.showHarmony" role="presentation"><a
|
||||||
<li role="presentation"><a href="#/editor">Manual Add</a></li>
|
href="#/harmonyactivities">Harmony Activities</a></li>
|
||||||
</ul>
|
<li ng-if="bridge.showHarmony" role="presentation"><a
|
||||||
|
href="#/harmonydevices">Harmony Devices</a></li>
|
||||||
|
<li role="presentation" class="active"><a href="#/nest">Nest</a></li>
|
||||||
|
<li ng-if="bridge.showHue" role="presentation"><a
|
||||||
|
href="#/huedevices">Hue Devices</a></li>
|
||||||
|
<li ng-if="bridge.showHal" role="presentation"><a
|
||||||
|
href="#/haldevices">HAL Devices</a></li>
|
||||||
|
<li role="presentation"><a href="#/editor">Manual Add</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<div class="panel panel-default bridgeServer" ng-if="!bridge.error">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h2 class="panel-title">Nest Items List</h2>
|
<h2 class="panel-title">Nest Items List</h2>
|
||||||
</div>
|
</div>
|
||||||
<ul class="list-group">
|
<div class="panel-body">
|
||||||
<li class="list-group-item">
|
<p class="text-muted">For any Nest Item, use the action buttons to
|
||||||
<p class="text-muted">For any Nest Item, use the action buttons to generate the device addition information below automatically.
|
generate the device addition information below automatically. Then
|
||||||
Then you can modify the name to anything you want that will be the keyword for Alexa. Click the 'Add Bridge Device' to finish that selection setup.
|
you can modify the name to anything you want that will be the keyword
|
||||||
The 'Already Configured Nest Items' list below will show what is already setup for your Nest.</p>
|
for Alexa. Click the 'Add Bridge Device' to finish that selection
|
||||||
|
setup. The 'Already Configured Nest Items' list below will show what
|
||||||
<scrollable-table watch="bridge.nestitems">
|
is already setup for your Nest.</p>
|
||||||
<table class="table table-bordered table-striped table-hover">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Row</th>
|
|
||||||
<th sortable-header col="name">Name</th>
|
|
||||||
<th sortable-header col="type">Type</th>
|
|
||||||
<th sortable-header col="location">Location</th>
|
|
||||||
<th>Actions</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tr ng-repeat="nestitem in bridge.nestitems | availableNestItemId | orderBy:predicate:reverse">
|
|
||||||
<td>{{$index+1}}</td>
|
|
||||||
<td>{{nestitem.name}}</td>
|
|
||||||
<td>{{nestitem.type}}</td>
|
|
||||||
<td>{{nestitem.location}}</td>
|
|
||||||
<td>
|
|
||||||
<ul class="list-group">
|
|
||||||
<li ng-if="nestitem.type ==='Home' " class="list-group-item">
|
|
||||||
<button class="btn btn-success" type="submit"
|
|
||||||
ng-click="buildNestHomeUrls(nestitem)">Home/Away</button>
|
|
||||||
</li>
|
|
||||||
<li ng-if="nestitem.type ==='Thermostat' " class="list-group-item">
|
|
||||||
<p>
|
|
||||||
<button class="btn btn-success" type="submit"
|
|
||||||
ng-click="buildNestTempUrls(nestitem)">Temp</button>
|
|
||||||
<button class="btn btn-success" type="submit"
|
|
||||||
ng-click="buildNestHeatUrls(nestitem)">Heat</button>
|
|
||||||
<button class="btn btn-success" type="submit"
|
|
||||||
ng-click="buildNestCoolUrls(nestitem)">Cool</button>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<button class="btn btn-success" type="submit"
|
|
||||||
ng-click="buildNestRangeUrls(nestitem)">Range</button>
|
|
||||||
<button class="btn btn-success" type="submit"
|
|
||||||
ng-click="buildNestOffUrls(nestitem)">Off</button>
|
|
||||||
<button class="btn btn-success" type="submit"
|
|
||||||
ng-click="buildNestFanUrls(nestitem)">Fan</button>
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</scrollable-table>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div class="panel-heading">
|
|
||||||
<h2 class="panel-title">Already Configured Nest Items <a ng-click="toggleButtons()"><span class={{imgButtonsUrl}} aria-hidden="true"></span></a></h2>
|
|
||||||
</div>
|
</div>
|
||||||
<ul ng-if="buttonsVisible" class="list-group">
|
|
||||||
<li class="list-group-item">
|
<scrollable-table watch="bridge.nestitems">
|
||||||
<scrollable-table watch="bridge.nestitems">
|
<table class="table table-bordered table-striped table-hover">
|
||||||
<table class="table table-bordered table-striped table-hover">
|
<thead>
|
||||||
<thead>
|
<tr>
|
||||||
<tr>
|
<th>Row</th>
|
||||||
<th>Row</th>
|
<th sortable-header col="name">Name</th>
|
||||||
<th sortable-header col="name">Name</th>
|
<th sortable-header col="type">Type</th>
|
||||||
<th sortable-header col="id">Device Id</th>
|
<th sortable-header col="location">Location</th>
|
||||||
<th>mapId</th>
|
<th>Actions</th>
|
||||||
<th>Actions</th>
|
</tr>
|
||||||
</tr>
|
</thead>
|
||||||
</thead>
|
<tr
|
||||||
<tr ng-repeat="device in bridge.devices | unavailableNestItemId | orderBy:predicate:reverse">
|
ng-repeat="nestitem in bridge.nestitems | availableNestItemId | orderBy:predicate:reverse">
|
||||||
<td>{{$index+1}}</td>
|
<td>{{$index+1}}</td>
|
||||||
<td>{{device.name}}</td>
|
<td>{{nestitem.name}}</td>
|
||||||
<td>{{device.id}}</td>
|
<td>{{nestitem.type}}</td>
|
||||||
<td>{{device.mapId}}</td>
|
<td>{{nestitem.location}}</td>
|
||||||
<td><button class="btn btn-danger" type="submit"
|
<td>
|
||||||
ng-click="deleteDeviceByMapId(device.mapId, 'nest')">Delete</button></td>
|
<ul class="list-group">
|
||||||
</tr>
|
<li ng-if="nestitem.type ==='Home' " class="list-group-item">
|
||||||
</table>
|
<button class="btn btn-success" type="submit"
|
||||||
</scrollable-table>
|
ng-click="buildNestHomeUrls(nestitem)">Home/Away</button>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
<li ng-if="nestitem.type ==='Thermostat' " class="list-group-item">
|
||||||
|
<p>
|
||||||
|
<button class="btn btn-success" type="submit"
|
||||||
|
ng-click="buildNestTempUrls(nestitem)">Temp</button>
|
||||||
|
<button class="btn btn-success" type="submit"
|
||||||
|
ng-click="buildNestHeatUrls(nestitem)">Heat</button>
|
||||||
|
<button class="btn btn-success" type="submit"
|
||||||
|
ng-click="buildNestCoolUrls(nestitem)">Cool</button>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<button class="btn btn-success" type="submit"
|
||||||
|
ng-click="buildNestRangeUrls(nestitem)">Range</button>
|
||||||
|
<button class="btn btn-success" type="submit"
|
||||||
|
ng-click="buildNestOffUrls(nestitem)">Off</button>
|
||||||
|
<button class="btn btn-success" type="submit"
|
||||||
|
ng-click="buildNestFanUrls(nestitem)">Fan</button>
|
||||||
|
</p>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</scrollable-table>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel panel-default bridgeServer" ng-if="!bridge.error">
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h2 class="panel-title">
|
||||||
|
Already Configured Nest Items <a ng-click="toggleButtons()"><span
|
||||||
|
class={{imgButtonsUrl}} aria-hidden="true"></span></a>
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<scrollable-table ng-if="buttonsVisible" watch="bridge.nestitems">
|
||||||
|
<table class="table table-bordered table-striped table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Row</th>
|
||||||
|
<th sortable-header col="name">Name</th>
|
||||||
|
<th sortable-header col="id">Device Id</th>
|
||||||
|
<th>mapId</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tr
|
||||||
|
ng-repeat="device in bridge.devices | unavailableNestItemId | orderBy:predicate:reverse">
|
||||||
|
<td>{{$index+1}}</td>
|
||||||
|
<td>{{device.name}}</td>
|
||||||
|
<td>{{device.id}}</td>
|
||||||
|
<td>{{device.mapId}}</td>
|
||||||
|
<td><button class="btn btn-danger" type="submit"
|
||||||
|
ng-click="deleteDeviceByMapId(device.mapId, 'nest')">Delete</button></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</scrollable-table>
|
||||||
|
</div>
|
||||||
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h2 class="panel-title">Add a Bridge Device for a Nest Item</h2>
|
<h2 class="panel-title">Add a Bridge Device for a Nest Item</h2>
|
||||||
</div>
|
</div>
|
||||||
<ul class="list-group">
|
<div class="panel-body">
|
||||||
<li class="list-group-item">
|
<form class="form-horizontal">
|
||||||
<form class="form-horizontal">
|
<div class="form-group">
|
||||||
<div class="form-group">
|
<label class="col-xs-12 col-sm-2 control-label" for="device-name">Name
|
||||||
<label class="col-xs-12 col-sm-2 control-label" for="device-name">Name
|
</label>
|
||||||
</label>
|
|
||||||
|
|
||||||
<div class="col-xs-8 col-sm-7">
|
<div class="col-xs-8 col-sm-7">
|
||||||
<input type="text" class="form-control" id="device-name"
|
<input type="text" class="form-control" id="device-name"
|
||||||
ng-model="device.name" placeholder="Device Name">
|
ng-model="device.name" placeholder="Device Name">
|
||||||
</div>
|
|
||||||
<button type="submit" class="col-xs-4 col-sm-2 btn btn-primary" ng-click="addDevice()">
|
|
||||||
Add Bridge Device</button>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<button type="submit" class="col-xs-4 col-sm-2 btn btn-primary"
|
||||||
<div class="row">
|
ng-click="addDevice()">Add Bridge Device</button>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="row">
|
||||||
<label class="col-xs-12 col-sm-2 control-label" for="device-on-url">On
|
<label class="col-xs-12 col-sm-2 control-label" for="device-on-url">On
|
||||||
URL </label>
|
URL </label>
|
||||||
|
|
||||||
@@ -125,10 +136,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<button class="btn btn-danger" ng-click="clearDevice()">
|
<button class="btn btn-danger" ng-click="clearDevice()">
|
||||||
Clear Device</button>
|
Clear Device</button>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
</div>
|
||||||
<div class="row">
|
<div class="form-group">
|
||||||
|
<div class="row">
|
||||||
<label class="col-xs-12 col-sm-2 control-label"
|
<label class="col-xs-12 col-sm-2 control-label"
|
||||||
for="device-off-url">Off URL </label>
|
for="device-off-url">Off URL </label>
|
||||||
|
|
||||||
@@ -136,9 +147,18 @@
|
|||||||
<textarea rows="3" class="form-control" id="device-off-url"
|
<textarea rows="3" class="form-control" id="device-off-url"
|
||||||
ng-model="device.offUrl" placeholder="URL to turn device off"></textarea>
|
ng-model="device.offUrl" placeholder="URL to turn device off"></textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</div>
|
||||||
</li>
|
</form>
|
||||||
</ul>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<script type="text/ng-template" id="deleteMapandIdDialog">
|
||||||
|
<div class="ngdialog-message">
|
||||||
|
<h2>Device Map and Id?</h2>
|
||||||
|
<p>{{mapandid.mapType}} with {{mapandid.id}}</p>
|
||||||
|
<p>Are you Sure?</p>
|
||||||
|
</div>
|
||||||
|
<div class="ngdialog-buttons mt">
|
||||||
|
<button type="button" class="ngdialog-button ngdialog-button-error" ng-click="deleteMapandId(mapandid)">Delete</button>
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
@@ -1,50 +1,57 @@
|
|||||||
<ul class="nav nav-pills" role="tablist">
|
<ul class="nav nav-pills" role="tablist">
|
||||||
<li role="presentation"><a href="#">Bridge Devices</a></li>
|
<li role="presentation"><a href="#">Bridge Devices</a></li>
|
||||||
<li role="presentation" class="active"><a href="#/system">Bridge Control</a></li>
|
<li role="presentation" class="active"><a href="#/system">Bridge
|
||||||
<li role="presentation"><a href="#/logs">Logs</a></li>
|
Control</a></li>
|
||||||
<li ng-if="bridge.showVera" role="presentation"><a href="#/veradevices">Vera Devices</a></li>
|
<li role="presentation"><a href="#/logs">Logs</a></li>
|
||||||
<li ng-if="bridge.showVera" role="presentation"><a href="#/verascenes">Vera Scenes</a></li>
|
<li ng-if="bridge.showVera" role="presentation"><a
|
||||||
<li ng-if="bridge.showHarmony" role="presentation"><a href="#/harmonyactivities">Harmony Activities</a></li>
|
href="#/veradevices">Vera Devices</a></li>
|
||||||
<li ng-if="bridge.showHarmony" role="presentation"><a href="#/harmonydevices">Harmony Devices</a></li>
|
<li ng-if="bridge.showVera" role="presentation"><a
|
||||||
<li ng-if="bridge.showNest" role="presentation"><a href="#/nest">Nest</a></li>
|
href="#/verascenes">Vera Scenes</a></li>
|
||||||
<li role="presentation"><a href="#/editor">Manual Add</a></li>
|
<li ng-if="bridge.showHarmony" role="presentation"><a
|
||||||
</ul>
|
href="#/harmonyactivities">Harmony Activities</a></li>
|
||||||
|
<li ng-if="bridge.showHarmony" role="presentation"><a
|
||||||
|
href="#/harmonydevices">Harmony Devices</a></li>
|
||||||
|
<li ng-if="bridge.showNest" role="presentation"><a href="#/nest">Nest</a></li>
|
||||||
|
<li ng-if="bridge.showHue" role="presentation"><a
|
||||||
|
href="#/huedevices">Hue Devices</a></li>
|
||||||
|
<li ng-if="bridge.showHal" role="presentation"><a
|
||||||
|
href="#/haldevices">HAL Devices</a></li>
|
||||||
|
<li role="presentation"><a href="#/editor">Manual Add</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<div class="panel panel-default bridgeServer">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h1 class="panel-title">Bridge Settings</h1>
|
<h1 class="panel-title">Bridge Settings</h1>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
|
|
||||||
<form class="form-horizontal">
|
<form class="form-horizontal">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="col-xs-12 col-sm-2 control-label" for="bridge-base">Bridge
|
<label class="col-xs-12 col-sm-2 control-label" for="bridge-base">Bridge
|
||||||
server</label>
|
server</label>
|
||||||
|
|
||||||
<div class="col-xs-8 col-sm-7">
|
<div class="col-xs-8 col-sm-7">
|
||||||
<input id="bridge-base" class="form-control" type="text"
|
<input id="bridge-base" class="form-control" type="text"
|
||||||
ng-model="bridge.base" placeholder="URL to bridge">
|
ng-model="bridge.base" placeholder="URL to bridge">
|
||||||
</div>
|
|
||||||
<button type="submit" class="col-xs-2 col-sm-1 btn btn-primary"
|
|
||||||
ng-click="setBridgeUrl(bridge.base)">Load</button>
|
|
||||||
<button type="submit" class="col-xs-2 col-sm-1 btn btn-primary"
|
|
||||||
ng-click="goBridgeUrl(bridge.base)">Go</button>
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
<button type="submit" class="col-xs-2 col-sm-1 btn btn-primary"
|
||||||
<form name="form">
|
ng-click="goBridgeUrl(bridge.base)">Test</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<form name="form">
|
||||||
<p>
|
<p>
|
||||||
<button ng-disabled="form.$pristine || bridge.isInControl" class="btn btn-success" type="submit"
|
<button ng-disabled="bridge.isInControl"
|
||||||
ng-click="saveSettings()">Save</button>
|
class="btn btn-success" type="submit" ng-click="saveSettings()">Save</button>
|
||||||
<button ng-disabled="bridge.isInControl" class="btn btn-warning" type="submit"
|
<button ng-disabled="bridge.isInControl" class="btn btn-warning"
|
||||||
ng-click="bridgeReinit()">Bridge Reinitialize</button>
|
type="submit" ng-click="bridgeReinit()">Bridge
|
||||||
<button ng-disabled="bridge.isInControl" class="btn btn-danger" type="submit"
|
Reinitialize</button>
|
||||||
ng-click="bridgeStop()">Bridge Stop</button>
|
<button ng-disabled="bridge.isInControl" class="btn btn-danger"
|
||||||
<button class="btn btn-primary" type="submit"
|
type="submit" ng-click="bridgeStop()">Bridge Stop</button>
|
||||||
onclick="myRefresh()">Refresh</button>
|
<button class="btn btn-primary" type="submit" onclick="myRefresh()">Refresh</button>
|
||||||
<script>
|
<script>
|
||||||
function myRefresh() {
|
function myRefresh() {
|
||||||
location.reload();
|
location.reload();
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</p>
|
</p>
|
||||||
<table class="table table-bordered table-striped table-hover">
|
<table class="table table-bordered table-striped table-hover">
|
||||||
@@ -56,32 +63,41 @@
|
|||||||
</thead>
|
</thead>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Configuration Path and File</td>
|
<td>Configuration Path and File</td>
|
||||||
<td><input id="bridge-settings-configfile" class="form-control" type="text"
|
<td><input id="bridge-settings-configfile"
|
||||||
ng-model="bridge.settings.configfile" placeholder="data/ha-bridge.config"></td>
|
class="form-control" type="text"
|
||||||
|
ng-model="bridge.settings.configfile"
|
||||||
|
placeholder="data/ha-bridge.config"></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Device DB Path and File</td>
|
<td>Device DB Path and File</td>
|
||||||
<td><input id="bridge-settings-upnpdevicedb" class="form-control" type="text"
|
<td><input id="bridge-settings-upnpdevicedb"
|
||||||
ng-model="bridge.settings.upnpdevicedb" placeholder="data/device.db"></td>
|
class="form-control" type="text"
|
||||||
|
ng-model="bridge.settings.upnpdevicedb"
|
||||||
|
placeholder="data/device.db"></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>UPNP IP Address</td>
|
<td>UPNP IP Address</td>
|
||||||
<td><input id="bridge-settings-upnpconfigaddress" class="form-control" type="text"
|
<td><input id="bridge-settings-upnpconfigaddress"
|
||||||
ng-model="bridge.settings.upnpconfigaddress" placeholder="192.168.1.1"></td>
|
class="form-control" type="text"
|
||||||
|
ng-model="bridge.settings.upnpconfigaddress"
|
||||||
|
placeholder="192.168.1.1"></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Web Server Port</td>
|
<td>Web Server Port</td>
|
||||||
<td><input id="bridge-settings-serverport" class="form-control" type="number"
|
<td><input id="bridge-settings-serverport"
|
||||||
ng-model="bridge.settings.serverport" min="1" max="65535"></td>
|
class="form-control" type="number"
|
||||||
|
ng-model="bridge.settings.serverport" min="1" max="65535"></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>UPNP Response Port</td>
|
<td>UPNP Response Port</td>
|
||||||
<td><input id="bridge-settings-upnpresponseport" class="form-control" type="number"
|
<td><input id="bridge-settings-upnpresponseport"
|
||||||
ng-model="bridge.settings.upnpresponseport" min="1" max="65535"></td>
|
class="form-control" type="number"
|
||||||
|
ng-model="bridge.settings.upnpresponseport" min="1" max="65535"></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Vera Names and IP Addresses</td>
|
<td>Vera Names and IP Addresses</td>
|
||||||
<td><table class="table table-bordered table-striped table-hover">
|
<td><table
|
||||||
|
class="table table-bordered table-striped table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
@@ -96,19 +112,21 @@
|
|||||||
ng-click="removeVeratoSettings(vera.name, vera.ip)">Del</button></td>
|
ng-click="removeVeratoSettings(vera.name, vera.ip)">Del</button></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><input id="bridge-settings-next-vera-name" class="form-control" type="text"
|
<td><input id="bridge-settings-next-vera-name"
|
||||||
ng-model="newveraname" placeholder="A Vera"></td>
|
class="form-control" type="text" ng-model="newveraname"
|
||||||
<td><input id="bridge-settings-next-vera-ip" class="form-control" type="text"
|
placeholder="A Vera"></td>
|
||||||
ng-model="newveraip" placeholder="192.168.1.2"></td>
|
<td><input id="bridge-settings-next-vera-ip"
|
||||||
<td><button class="btn btn-success" type="submit"
|
class="form-control" type="text" ng-model="newveraip"
|
||||||
|
placeholder="192.168.1.2"></td>
|
||||||
|
<td><button class="btn btn-success" type="submit"
|
||||||
ng-click="addVeratoSettings(newveraname, newveraip)">Add</button></td>
|
ng-click="addVeratoSettings(newveraname, newveraip)">Add</button></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table></td>
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Harmony Names and IP Addresses</td>
|
<td>Harmony Names and IP Addresses</td>
|
||||||
<td><table class="table table-bordered table-striped table-hover">
|
<td><table
|
||||||
|
class="table table-bordered table-striped table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
@@ -123,99 +141,180 @@
|
|||||||
ng-click="removeHarmonytoSettings(harmony.name, harmony.ip)">Del</button></td>
|
ng-click="removeHarmonytoSettings(harmony.name, harmony.ip)">Del</button></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><input id="bridge-settings-next-harmony-name" class="form-control" type="text"
|
<td><input id="bridge-settings-next-harmony-name"
|
||||||
ng-model="newharmonyname" placeholder="A Harmony"></td>
|
class="form-control" type="text" ng-model="newharmonyname"
|
||||||
<td><input id="bridge-settings-next-harmony-ip" class="form-control" type="text"
|
placeholder="A Harmony"></td>
|
||||||
ng-model="newharmonyip" placeholder="192.168.1.3"></td>
|
<td><input id="bridge-settings-next-harmony-ip"
|
||||||
<td><button class="btn btn-success" type="submit"
|
class="form-control" type="text" ng-model="newharmonyip"
|
||||||
|
placeholder="192.168.1.3"></td>
|
||||||
|
<td><button class="btn btn-success" type="submit"
|
||||||
ng-click="addHarmonytoSettings(newharmonyname, newharmonyip)">Add</button></td>
|
ng-click="addHarmonytoSettings(newharmonyname, newharmonyip)">Add</button></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table></td>
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Harmony Username</td>
|
<td>Harmony Username</td>
|
||||||
<td><input id="bridge-settings-harmonyuser" class="form-control" type="text"
|
<td><input id="bridge-settings-harmonyuser"
|
||||||
ng-model="bridge.settings.harmonyuser" placeholder="someone@gmail.com"></td>
|
class="form-control" type="text"
|
||||||
|
ng-model="bridge.settings.harmonyuser"
|
||||||
|
placeholder="someone@gmail.com"></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Harmony Password</td>
|
<td>Harmony Password</td>
|
||||||
<td><input id="bridge-settings-harmonypwd" class="form-control" type="password"
|
<td><input id="bridge-settings-harmonypwd"
|
||||||
ng-model="bridge.settings.harmonypwd" placeholder="thepassword"></td>
|
class="form-control" type="password"
|
||||||
|
ng-model="bridge.settings.harmonypwd" placeholder="thepassword"></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Button Press Sleep Interval (ms)</td>
|
<td>Hue Names and IP Addresses</td>
|
||||||
<td><input id="bridge-settings-buttonsleep" class="form-control" type="number" name="input"
|
<td><table
|
||||||
ng-model="bridge.settings.buttonsleep" min="100" max="9999"></td>
|
class="table table-bordered table-striped table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>IP</th>
|
||||||
|
<th>Manage</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tr ng-repeat="hue in bridge.settings.hueaddress.devices">
|
||||||
|
<td>{{hue.name}}</td>
|
||||||
|
<td>{{hue.ip}}</td>
|
||||||
|
<td><button class="btn btn-danger" type="submit"
|
||||||
|
ng-click="removeHuetoSettings(hue.name, hue.ip)">Del</button></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><input id="bridge-settings-next-hue-name"
|
||||||
|
class="form-control" type="text" ng-model="newhuename"
|
||||||
|
placeholder="A Hue"></td>
|
||||||
|
<td><input id="bridge-settings-next-hue-ip"
|
||||||
|
class="form-control" type="text" ng-model="newhueip"
|
||||||
|
placeholder="192.168.1.3"></td>
|
||||||
|
<td><button class="btn btn-success" type="submit"
|
||||||
|
ng-click="addHuetoSettings(newhuename, newhueip)">Add</button></td>
|
||||||
|
</tr>
|
||||||
|
</table></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>HAL Names and IP Addresses</td>
|
||||||
|
<td><table
|
||||||
|
class="table table-bordered table-striped table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>IP</th>
|
||||||
|
<th>Manage</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tr ng-repeat="hal in bridge.settings.haladdress.devices">
|
||||||
|
<td>{{hal.name}}</td>
|
||||||
|
<td>{{hal.ip}}</td>
|
||||||
|
<td><button class="btn btn-danger" type="submit"
|
||||||
|
ng-click="removeHaltoSettings(hal.name, hal.ip)">Del</button></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><input id="bridge-settings-next-hal-name"
|
||||||
|
class="form-control" type="text" ng-model="newhalname"
|
||||||
|
placeholder="A Hal"></td>
|
||||||
|
<td><input id="bridge-settings-next-hal-ip"
|
||||||
|
class="form-control" type="text" ng-model="newhalip"
|
||||||
|
placeholder="192.168.1.3:82"></td>
|
||||||
|
<td><button class="btn btn-success" type="submit"
|
||||||
|
ng-click="addHaltoSettings(newhalname, newhalip)">Add</button></td>
|
||||||
|
</tr>
|
||||||
|
</table></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>HAL Token</td>
|
||||||
|
<td><input id="bridge-settings-haltoken" class="form-control"
|
||||||
|
type="password" ng-model="bridge.settings.haltoken"
|
||||||
|
placeholder="thetoken"></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Nest Username</td>
|
<td>Nest Username</td>
|
||||||
<td><input id="bridge-settings-nestuser" class="form-control" type="text"
|
<td><input id="bridge-settings-nestuser" class="form-control"
|
||||||
ng-model="bridge.settings.nestuser" placeholder="someone@gmail.com"></td>
|
type="text" ng-model="bridge.settings.nestuser"
|
||||||
|
placeholder="someone@gmail.com"></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Nest Password</td>
|
<td>Nest Password</td>
|
||||||
<td><input id="bridge-settings-nestpwd" class="form-control" type="password"
|
<td><input id="bridge-settings-nestpwd" class="form-control"
|
||||||
ng-model="bridge.settings.nestpwd" placeholder="thepassword"></td>
|
type="password" ng-model="bridge.settings.nestpwd"
|
||||||
</tr>
|
placeholder="thepassword"></td>
|
||||||
<tr>
|
|
||||||
<td>Log Messages to Buffer</td>
|
|
||||||
<td><input id="bridge-settings-numberoflogmessages" class="form-control" type="number"
|
|
||||||
ng-model="bridge.settings.numberoflogmessages" min="100" max="65535"></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>UPNP Strict Handling</td>
|
|
||||||
<td><input type="checkbox" ng-model="bridge.settings.upnpstrict"
|
|
||||||
ng-true-value=true ng-false-value=false> {{bridge.settings.upnpstrict}}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Trace UPNP Calls</td>
|
|
||||||
<td><input type="checkbox" ng-model="bridge.settings.traceupnp"
|
|
||||||
ng-true-value=true ng-false-value=false> {{bridge.settings.traceupnp}}</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Nest Temp Farenheit</td>
|
<td>Nest Temp Farenheit</td>
|
||||||
<td><input type="checkbox" ng-model="bridge.settings.farenheit"
|
<td><input type="checkbox"
|
||||||
ng-true-value=true ng-false-value=false> {{bridge.settings.farenheit}}</td>
|
ng-model="bridge.settings.farenheit" ng-true-value=true
|
||||||
|
ng-false-value=false> {{bridge.settings.farenheit}}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Button Press/Call Item Loop Sleep Interval (ms)</td>
|
||||||
|
<td><input id="bridge-settings-buttonsleep"
|
||||||
|
class="form-control" type="number" name="input"
|
||||||
|
ng-model="bridge.settings.buttonsleep" min="100" max="9999"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Log Messages to Buffer</td>
|
||||||
|
<td><input id="bridge-settings-numberoflogmessages"
|
||||||
|
class="form-control" type="number"
|
||||||
|
ng-model="bridge.settings.numberoflogmessages" min="100"
|
||||||
|
max="65535"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>UPNP Strict Handling</td>
|
||||||
|
<td><input type="checkbox"
|
||||||
|
ng-model="bridge.settings.upnpstrict" ng-true-value=true
|
||||||
|
ng-false-value=false> {{bridge.settings.upnpstrict}}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Trace UPNP Calls</td>
|
||||||
|
<td><input type="checkbox"
|
||||||
|
ng-model="bridge.settings.traceupnp" ng-true-value=true
|
||||||
|
ng-false-value=false> {{bridge.settings.traceupnp}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="panel panel-default backup">
|
</div>
|
||||||
<div class="panel-heading">
|
<div class="panel panel-default">
|
||||||
<h1 class="panel-title">Bridge Settings Backup <a ng-click="toggle()"><span class={{imgUrl}} aria-hidden="true"></a></h1>
|
<div class="panel-heading">
|
||||||
</div>
|
<h1 class="panel-title">
|
||||||
<div ng-if="visible" class="animate-if" class="panel-body">
|
Bridge Settings Backup <a ng-click="toggle()"><span
|
||||||
<form class="form-horizontal">
|
class={{imgUrl}} aria-hidden="true"></a>
|
||||||
<div class="form-group">
|
</h1>
|
||||||
<label class="col-xs-12 col-sm-2 control-label" for="backup-name">Backup Settings File Name</label>
|
</div>
|
||||||
|
<div ng-if="visible" class="animate-if" class="panel-body">
|
||||||
|
<p>Control your backups from this area. Use the default name by hitting backup or specify your own.</p>
|
||||||
|
<form class="form-horizontal">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-xs-12 col-sm-2 control-label" for="backup-name">Backup
|
||||||
|
Settings File Name</label>
|
||||||
|
|
||||||
<div class="col-xs-8 col-sm-7">
|
<div class="col-xs-8 col-sm-7">
|
||||||
<input id="backup-name" class="form-control" type="text"
|
<input id="backup-name" class="form-control" type="text"
|
||||||
ng-model="optionalbackupname" placeholder="Optional">
|
ng-model="optionalbackupname" placeholder="Optional">
|
||||||
</div>
|
|
||||||
<button type="submit" class="btn btn-primary"
|
|
||||||
ng-click="backupSettings(optionalbackupname)">Backup Settings</button>
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
<button type="submit" class="btn btn-primary"
|
||||||
<table class="table table-bordered table-striped table-hover">
|
ng-click="backupSettings(optionalbackupname)">Backup
|
||||||
<thead>
|
Settings</button>
|
||||||
<tr>
|
</div>
|
||||||
<th>Filename</th>
|
</form>
|
||||||
<th>Actions</th>
|
<table class="table table-bordered table-striped table-hover">
|
||||||
</tr>
|
<thead>
|
||||||
</thead>
|
<tr>
|
||||||
<tr ng-repeat="backup in bridge.configs">
|
<th>Filename</th>
|
||||||
<td>{{backup}}</td>
|
<th>Actions</th>
|
||||||
<td>
|
|
||||||
<button class="btn btn-danger" type="submit"
|
|
||||||
ng-click="restoreSettings(backup)">Restore</button>
|
|
||||||
<button class="btn btn-warning" type="submit"
|
|
||||||
ng-click="deleteSettingsBackup(backup)">Delete</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</thead>
|
||||||
</div>
|
<tr ng-repeat="backup in bridge.configs">
|
||||||
|
<td>{{backup}}</td>
|
||||||
|
<td>
|
||||||
|
<button class="btn btn-danger" type="submit"
|
||||||
|
ng-click="restoreSettings(backup)">Restore</button>
|
||||||
|
<button class="btn btn-warning" type="submit"
|
||||||
|
ng-click="deleteSettingsBackup(backup)">Delete</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
@@ -1,125 +1,146 @@
|
|||||||
<ul class="nav nav-pills" role="tablist">
|
<ul class="nav nav-pills" role="tablist">
|
||||||
<li role="presentation"><a href="#">Bridge Devices</a></li>
|
<li role="presentation"><a href="#">Bridge Devices</a></li>
|
||||||
<li role="presentation"><a href="#/system">Bridge Control</a></li>
|
<li role="presentation"><a href="#/system">Bridge Control</a></li>
|
||||||
<li role="presentation"><a href="#/logs">Logs</a></li>
|
<li role="presentation"><a href="#/logs">Logs</a></li>
|
||||||
<li role="presentation" class="active"><a href="#/veradevices">Vera Devices</a></li>
|
<li role="presentation" class="active"><a href="#/veradevices">Vera
|
||||||
<li role="presentation"><a href="#/verascenes">Vera Scenes</a></li>
|
Devices</a></li>
|
||||||
<li ng-if="bridge.showHarmony" role="presentation"><a href="#/harmonyactivities">Harmony Activities</a></li>
|
<li role="presentation"><a href="#/verascenes">Vera Scenes</a></li>
|
||||||
<li ng-if="bridge.showHarmony" role="presentation"><a href="#/harmonydevices">Harmony Devices</a></li>
|
<li ng-if="bridge.showHarmony" role="presentation"><a
|
||||||
<li ng-if="bridge.showNest" role="presentation"><a href="#/nest">Nest</a></li>
|
href="#/harmonyactivities">Harmony Activities</a></li>
|
||||||
<li role="presentation"><a href="#/editor">Manual Add</a></li>
|
<li ng-if="bridge.showHarmony" role="presentation"><a
|
||||||
</ul>
|
href="#/harmonydevices">Harmony Devices</a></li>
|
||||||
|
<li ng-if="bridge.showNest" role="presentation"><a href="#/nest">Nest</a></li>
|
||||||
|
<li ng-if="bridge.showHue" role="presentation"><a
|
||||||
|
href="#/huedevices">Hue Devices</a></li>
|
||||||
|
<li ng-if="bridge.showHal" role="presentation"><a
|
||||||
|
href="#/haldevices">HAL Devices</a></li>
|
||||||
|
<li role="presentation"><a href="#/editor">Manual Add</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<div class="panel panel-default bridgeServer" ng-if="!bridge.error">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h2 class="panel-title">Vera Device List ({{bridge.veradevices.length}})</h2>
|
<h2 class="panel-title">Vera Device List
|
||||||
|
({{bridge.veradevices.length}})</h2>
|
||||||
</div>
|
</div>
|
||||||
<ul class="list-group">
|
<div class="panel-body">
|
||||||
<li class="list-group-item">
|
<p class="text-muted">For any Vera Device, use the action buttons
|
||||||
<p class="text-muted">For any Vera Device, use the action buttons to generate the device addition information below automatically.
|
to generate the device addition information below automatically. Then
|
||||||
Then you can modify the name to anything you want that will be the keyword for Alexa. Click the 'Add Bridge Device' to finish that selection setup.
|
you can modify the name to anything you want that will be the keyword
|
||||||
The 'Already Configured Vera Devices' list below will show what is already setup for your Vera.</p>
|
for Alexa. Click the 'Add Bridge Device' to finish that selection
|
||||||
<p>Also, use this select menu for which type of dim
|
setup. The 'Already Configured Vera Devices' list below will show
|
||||||
control you would like to be generated:
|
what is already setup for your Vera.</p>
|
||||||
<select name="device-dim-control" id="device-dim-control" ng-model="device_dim_control">
|
<p>
|
||||||
<option value="">none</option>
|
Also, use this select menu for which type of dim control you would
|
||||||
<option value="${intensity..byte}">Pass-thru Value</option>
|
like to be generated: <select name="device-dim-control"
|
||||||
<option value="${intensity.percent}">Percentage</option>
|
id="device-dim-control" ng-model="device_dim_control">
|
||||||
<option value="${intensity.math(X*1)}">Custom Math</option>
|
<option value="">none</option>
|
||||||
</select>
|
<option value="${intensity.byte}">Pass-thru Value</option>
|
||||||
</p>
|
<option value="${intensity.percent}">Percentage</option>
|
||||||
<p>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.
|
<option value="${intensity.math(X*1)}">Custom Math</option>
|
||||||
Your items will be added with on and off or dim and off if selected with the name of the device from the Vera.
|
</select>
|
||||||
</p>
|
</p>
|
||||||
<scrollable-table watch="bridge.veradevices">
|
<p>Use the check boxes by the names to use the bulk addition
|
||||||
<table class="table table-bordered table-striped table-hover">
|
feature. Select your items and dim control type if wanted, then click
|
||||||
<thead>
|
bulk add below. Your items will be added with on and off or dim and
|
||||||
<tr>
|
off if selected with the name of the device from the Vera.</p>
|
||||||
<th>Row</th>
|
</div>
|
||||||
<th sortable-header col="name">Name</th>
|
<scrollable-table watch="bridge.veradevices">
|
||||||
<th sortable-header col="id">Id</th>
|
<table class="table table-bordered table-striped table-hover">
|
||||||
<th sortable-header col="category">Category</th>
|
<thead>
|
||||||
<th sortable-header col="room">Room</th>
|
<tr>
|
||||||
<th sortable-header col="veraname">Vera</th>
|
<th>Row</th>
|
||||||
<th>Actions</th>
|
<th sortable-header col="name"><span><input type="checkbox" name="selectAll"
|
||||||
</tr>
|
value="{{selectAll}}"
|
||||||
</thead>
|
ng-checked="selectAll"
|
||||||
<tr ng-repeat="veradevice in bridge.veradevices | availableVeraDeviceId">
|
ng-click="toggleSelectAll()"> Name</span></th>
|
||||||
<td>{{$index+1}}</td>
|
<th sortable-header col="id">Id</th>
|
||||||
<td><input type="checkbox" name="bulk.devices[]" value="{{veradevice.id}}" ng-checked="bulk.devices.indexOf(veradevice.id) > -1" ng-click="toggleSelection(veradevice.id)"> {{veradevice.name}}</td>
|
<th sortable-header col="category">Category</th>
|
||||||
<td>{{veradevice.id}}</td>
|
<th sortable-header col="room">Room</th>
|
||||||
<td>{{veradevice.category}}</td>
|
<th sortable-header col="veraname">Vera</th>
|
||||||
<td>{{veradevice.room}}</td>
|
<th>Actions</th>
|
||||||
<td>{{veradevice.veraname}}</td>
|
</tr>
|
||||||
<td>
|
</thead>
|
||||||
<button class="btn btn-success" type="submit"
|
<tr
|
||||||
ng-click="buildDeviceUrls(veradevice, device_dim_control)">Generate
|
ng-repeat="veradevice in bridge.veradevices | availableVeraDeviceId">
|
||||||
Device URLs</button>
|
<td>{{$index+1}}</td>
|
||||||
</td>
|
<td><input type="checkbox" name="bulk.devices[]"
|
||||||
</tr>
|
value="{{veradevice.id}}"
|
||||||
</table>
|
ng-checked="bulk.devices.indexOf(veradevice.id) > -1"
|
||||||
</scrollable-table>
|
ng-click="toggleSelection(veradevice.id)">
|
||||||
<p>
|
{{veradevice.name}}</td>
|
||||||
|
<td>{{veradevice.id}}</td>
|
||||||
|
<td>{{veradevice.category}}</td>
|
||||||
|
<td>{{veradevice.room}}</td>
|
||||||
|
<td>{{veradevice.veraname}}</td>
|
||||||
|
<td>
|
||||||
<button class="btn btn-success" type="submit"
|
<button class="btn btn-success" type="submit"
|
||||||
ng-click="bulkAddDevices(device_dim_control)">Bulk Add ({{bulk.devices.length}})</button>
|
ng-click="buildDeviceUrls(veradevice, device_dim_control)">Generate
|
||||||
</p>
|
Bridge Device</button>
|
||||||
</li>
|
</td>
|
||||||
</ul>
|
</tr>
|
||||||
<div class="panel-heading">
|
</table>
|
||||||
<h2 class="panel-title">Already Configured Vera Devices <a ng-click="toggleButtons()"><span class={{imgButtonsUrl}} aria-hidden="true"></span></a></a></h2>
|
</scrollable-table>
|
||||||
|
<div class="panel-footer">
|
||||||
|
<button class="btn btn-success" type="submit"
|
||||||
|
ng-click="bulkAddDevices(device_dim_control)">Bulk Add
|
||||||
|
({{bulk.devices.length}})</button>
|
||||||
</div>
|
</div>
|
||||||
<ul ng-if="buttonsVisible" class="list-group">
|
|
||||||
<li class="list-group-item">
|
|
||||||
<scrollable-table watch="bridge.veradevices">
|
|
||||||
<table class="table table-bordered table-striped table-hover">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Row</th>
|
|
||||||
<th sortable-header col="name">Name</th>
|
|
||||||
<th sortable-header col="id">Id</th>
|
|
||||||
<th sortable-header col="category">Category</th>
|
|
||||||
<th sortable-header col="room">Room</th>
|
|
||||||
<th sortable-header col="veraname">Vera</th>
|
|
||||||
<th>Actions</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tr ng-repeat="veradevice in bridge.veradevices | unavailableVeraDeviceId">
|
|
||||||
<td>{{$index+1}}</td>
|
|
||||||
<td>{{veradevice.name}}</td>
|
|
||||||
<td>{{veradevice.id}}</td>
|
|
||||||
<td>{{veradevice.category}}</td>
|
|
||||||
<td>{{veradevice.room}}</td>
|
|
||||||
<td>{{veradevice.veraname}}</td>
|
|
||||||
<td>
|
|
||||||
<button class="btn btn-danger" type="submit"
|
|
||||||
ng-click="deleteDeviceByMapId(veradevice.id, 'veraDevice')">Delete</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</scrollable-table>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="panel panel-default bridgeServer" ng-if="!bridge.error">
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h2 class="panel-title">
|
||||||
|
Already Configured Vera Devices <a ng-click="toggleButtons()"><span
|
||||||
|
class={{imgButtonsUrl}} aria-hidden="true"></span></a></a>
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<scrollable-table ng-if="buttonsVisible" watch="bridge.veradevices">
|
||||||
|
<table class="table table-bordered table-striped table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Row</th>
|
||||||
|
<th sortable-header col="name">Name</th>
|
||||||
|
<th sortable-header col="id">Id</th>
|
||||||
|
<th sortable-header col="category">Category</th>
|
||||||
|
<th sortable-header col="room">Room</th>
|
||||||
|
<th sortable-header col="veraname">Vera</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tr
|
||||||
|
ng-repeat="veradevice in bridge.veradevices | unavailableVeraDeviceId">
|
||||||
|
<td>{{$index+1}}</td>
|
||||||
|
<td>{{veradevice.name}}</td>
|
||||||
|
<td>{{veradevice.id}}</td>
|
||||||
|
<td>{{veradevice.category}}</td>
|
||||||
|
<td>{{veradevice.room}}</td>
|
||||||
|
<td>{{veradevice.veraname}}</td>
|
||||||
|
<td>
|
||||||
|
<button class="btn btn-danger" type="submit"
|
||||||
|
ng-click="deleteDeviceByMapId(veradevice.id, 'veraDevice')">Delete</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</scrollable-table>
|
||||||
|
</div>
|
||||||
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h2 class="panel-title">Add Bridge Device for a Vera Device</h2>
|
<h2 class="panel-title">Add Bridge Device for a Vera Device</h2>
|
||||||
</div>
|
</div>
|
||||||
<ul class="list-group">
|
<div class="panel-body">
|
||||||
<li class="list-group-item">
|
<form class="form-horizontal">
|
||||||
<form class="form-horizontal">
|
<div class="form-group">
|
||||||
<div class="form-group">
|
<label class="col-xs-12 col-sm-2 control-label" for="device-name">Name
|
||||||
<label class="col-xs-12 col-sm-2 control-label" for="device-name">Name
|
</label>
|
||||||
</label>
|
|
||||||
|
|
||||||
<div class="col-xs-8 col-sm-7">
|
<div class="col-xs-8 col-sm-7">
|
||||||
<input type="text" class="form-control" id="device-name"
|
<input type="text" class="form-control" id="device-name"
|
||||||
ng-model="device.name" placeholder="Device Name">
|
ng-model="device.name" placeholder="Device Name">
|
||||||
</div>
|
|
||||||
<button type="submit" class="col-xs-4 col-sm-2 btn btn-primary" ng-click="addDevice()">
|
|
||||||
Add Bridge Device</button>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<button type="submit" class="col-xs-4 col-sm-2 btn btn-primary"
|
||||||
<div class="row">
|
ng-click="addDevice()">Add Bridge Device</button>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="row">
|
||||||
<label class="col-xs-12 col-sm-2 control-label" for="device-on-url">On
|
<label class="col-xs-12 col-sm-2 control-label" for="device-on-url">On
|
||||||
URL </label>
|
URL </label>
|
||||||
|
|
||||||
@@ -132,26 +153,35 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<label class="col-xs-12 col-sm-2 control-label" for="device-dim-url">Dim
|
<label class="col-xs-12 col-sm-2 control-label"
|
||||||
URL </label>
|
for="device-dim-url">Dim URL </label>
|
||||||
|
|
||||||
<div class="col-xs-8 col-sm-7">
|
<div class="col-xs-8 col-sm-7">
|
||||||
<textarea rows="3" class="form-control" id="device-dim-url"
|
<textarea rows="3" class="form-control" id="device-dim-url"
|
||||||
ng-model="device.dimUrl" placeholder="URL to dim device"></textarea>
|
ng-model="device.dimUrl" placeholder="URL to dim device"></textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<label class="col-xs-12 col-sm-2 control-label"
|
<label class="col-xs-12 col-sm-2 control-label"
|
||||||
for="device-off-url">Off URL </label>
|
for="device-off-url">Off URL </label>
|
||||||
|
|
||||||
<div class="col-xs-8 col-sm-7">
|
<div class="col-xs-8 col-sm-7">
|
||||||
<textarea rows="3" class="form-control" id="device-off-url"
|
<textarea rows="3" class="form-control" id="device-off-url"
|
||||||
ng-model="device.offUrl" placeholder="URL to turn device off"></textarea>
|
ng-model="device.offUrl" placeholder="URL to turn device off"></textarea>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</form>
|
||||||
</form>
|
</div>
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
|
<script type="text/ng-template" id="deleteMapandIdDialog">
|
||||||
|
<div class="ngdialog-message">
|
||||||
|
<h2>Device Map and Id?</h2>
|
||||||
|
<p>{{mapandid.mapType}} with {{mapandid.id}}</p>
|
||||||
|
<p>Are you Sure?</p>
|
||||||
|
</div>
|
||||||
|
<div class="ngdialog-buttons mt">
|
||||||
|
<button type="button" class="ngdialog-button ngdialog-button-error" ng-click="deleteMapandId(mapandid)">Delete</button>
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
@@ -1,106 +1,115 @@
|
|||||||
<ul class="nav nav-pills" role="tablist">
|
<ul class="nav nav-pills" role="tablist">
|
||||||
<li role="presentation"><a href="#">Bridge Devices</a></li>
|
<li role="presentation"><a href="#">Bridge Devices</a></li>
|
||||||
<li role="presentation"><a href="#/system">Bridge Control</a></li>
|
<li role="presentation"><a href="#/system">Bridge Control</a></li>
|
||||||
<li role="presentation"><a href="#/logs">Logs</a></li>
|
<li role="presentation"><a href="#/logs">Logs</a></li>
|
||||||
<li role="presentation"><a href="#/veradevices">Vera Devices</a></li>
|
<li role="presentation"><a href="#/veradevices">Vera Devices</a></li>
|
||||||
<li role="presentation" class="active"><a href="#/verascenes">Vera Scenes</a></li>
|
<li role="presentation" class="active"><a href="#/verascenes">Vera
|
||||||
<li ng-if="bridge.showHarmony" role="presentation"><a href="#/harmonyactivities">Harmony Activities</a></li>
|
Scenes</a></li>
|
||||||
<li ng-if="bridge.showHarmony" role="presentation"><a href="#/harmonydevices">Harmony Devices</a></li>
|
<li ng-if="bridge.showHarmony" role="presentation"><a
|
||||||
<li ng-if="bridge.showNest" role="presentation"><a href="#/nest">Nest</a></li>
|
href="#/harmonyactivities">Harmony Activities</a></li>
|
||||||
<li role="presentation"><a href="#/editor">Manual Add</a></li>
|
<li ng-if="bridge.showHarmony" role="presentation"><a
|
||||||
</ul>
|
href="#/harmonydevices">Harmony Devices</a></li>
|
||||||
|
<li ng-if="bridge.showNest" role="presentation"><a href="#/nest">Nest</a></li>
|
||||||
|
<li ng-if="bridge.showHue" role="presentation"><a
|
||||||
|
href="#/huedevices">Hue Devices</a></li>
|
||||||
|
<li ng-if="bridge.showHal" role="presentation"><a
|
||||||
|
href="#/haldevices">HAL Devices</a></li>
|
||||||
|
<li role="presentation"><a href="#/editor">Manual Add</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<div class="panel panel-default bridgeServer" ng-if="!bridge.error">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h2 class="panel-title">Vera Scene List</h2>
|
<h2 class="panel-title">Vera Scene List</h2>
|
||||||
</div>
|
</div>
|
||||||
<ul class="list-group">
|
<div class="panel-body">
|
||||||
<li class="list-group-item">
|
<p class="text-muted">For any Vera Scene, use the action buttons
|
||||||
<p class="text-muted">For any Vera Scene, use the action buttons to generate the device addition information below automatically.
|
to generate the device addition information below automatically. Then
|
||||||
Then you can modify the name to anything you want that will be the keyword for Alexa. Click the 'Add Bridge Device' to finish that selection setup.
|
you can modify the name to anything you want that will be the keyword
|
||||||
The 'Already Configured Vera Scenes' list below will show what is already setup for your Vera.</p>
|
for Alexa. Click the 'Add Bridge Device' to finish that selection
|
||||||
|
setup. The 'Already Configured Vera Scenes' list below will show what
|
||||||
<scrollable-table watch="bridge.verascenes">
|
is already setup for your Vera.</p>
|
||||||
<table class="table table-bordered table-striped table-hover">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Row</th>
|
|
||||||
<th sortable-header col="name">Name</th>
|
|
||||||
<th sortable-header col="id">Id</th>
|
|
||||||
<th sortable-header col="room">Room</th>
|
|
||||||
<th sortable-header col="veraname">Vera</th>
|
|
||||||
<th>Actions</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tr ng-repeat="verascene in bridge.verascenes | availableVeraSceneId">
|
|
||||||
<td>{{$index+1}}</td>
|
|
||||||
<td>{{verascene.name}}</td>
|
|
||||||
<td>{{verascene.id}}</td>
|
|
||||||
<td>{{verascene.room}}</td>
|
|
||||||
<td>{{verascene.veraname}}</td>
|
|
||||||
<td>
|
|
||||||
<button class="btn btn-success" type="submit"
|
|
||||||
ng-click="buildSceneUrls(verascene)">Generate
|
|
||||||
Scene URLs</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</scrollable-table>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div class="panel-heading">
|
|
||||||
<h2 class="panel-title">Already Configured Vera Scenes <a ng-click="toggleButtons()"><span class={{imgButtonsUrl}} aria-hidden="true"></span></a></h2>
|
|
||||||
</div>
|
</div>
|
||||||
<ul ng-if="buttonsVisible" class="list-group">
|
|
||||||
<li class="list-group-item">
|
<scrollable-table watch="bridge.verascenes">
|
||||||
<scrollable-table watch="bridge.verascenes">
|
<table class="table table-bordered table-striped table-hover">
|
||||||
<table class="table table-bordered table-striped table-hover">
|
<thead>
|
||||||
<thead>
|
<tr>
|
||||||
<tr>
|
<th>Row</th>
|
||||||
<th>Row</th>
|
<th sortable-header col="name">Name</th>
|
||||||
<th sortable-header col="name">Name</th>
|
<th sortable-header col="id">Id</th>
|
||||||
<th sortable-header col="id">Id</th>
|
<th sortable-header col="room">Room</th>
|
||||||
<th sortable-header col="room">Room</th>
|
<th sortable-header col="veraname">Vera</th>
|
||||||
<th sortable-header col="veraname">Vera</th>
|
<th>Actions</th>
|
||||||
<th>Actions</th>
|
</tr>
|
||||||
</tr>
|
</thead>
|
||||||
</thead>
|
<tr ng-repeat="verascene in bridge.verascenes | availableVeraSceneId">
|
||||||
<tr ng-repeat="verascene in bridge.verascenes | unavailableVeraSceneId">
|
<td>{{$index+1}}</td>
|
||||||
<td>{{$index+1}}</td>
|
<td>{{verascene.name}}</td>
|
||||||
<td>{{verascene.name}}</td>
|
<td>{{verascene.id}}</td>
|
||||||
<td>{{verascene.id}}</td>
|
<td>{{verascene.room}}</td>
|
||||||
<td>{{verascene.room}}</td>
|
<td>{{verascene.veraname}}</td>
|
||||||
<td>{{verascene.veraname}}</td>
|
<td>
|
||||||
<td>
|
<button class="btn btn-success" type="submit"
|
||||||
<button class="btn btn-danger" type="submit"
|
ng-click="buildSceneUrls(verascene)">Generate Bridge
|
||||||
ng-click="deleteDeviceByMapId(verascene.id, 'veraScene')">Delete</button>
|
Device</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</scrollable-table>
|
</scrollable-table>
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="panel panel-default bridgeServer" ng-if="!bridge.error">
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h2 class="panel-title">
|
||||||
|
Already Configured Vera Scenes <a ng-click="toggleButtons()"><span
|
||||||
|
class={{imgButtonsUrl}} aria-hidden="true"></span></a>
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<scrollable-table ng-if="buttonsVisible" watch="bridge.verascenes">
|
||||||
|
<table class="table table-bordered table-striped table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Row</th>
|
||||||
|
<th sortable-header col="name">Name</th>
|
||||||
|
<th sortable-header col="id">Id</th>
|
||||||
|
<th sortable-header col="room">Room</th>
|
||||||
|
<th sortable-header col="veraname">Vera</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tr
|
||||||
|
ng-repeat="verascene in bridge.verascenes | unavailableVeraSceneId">
|
||||||
|
<td>{{$index+1}}</td>
|
||||||
|
<td>{{verascene.name}}</td>
|
||||||
|
<td>{{verascene.id}}</td>
|
||||||
|
<td>{{verascene.room}}</td>
|
||||||
|
<td>{{verascene.veraname}}</td>
|
||||||
|
<td>
|
||||||
|
<button class="btn btn-danger" type="submit"
|
||||||
|
ng-click="deleteDeviceByMapId(verascene.id, 'veraScene')">Delete</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</scrollable-table>
|
||||||
|
</div>
|
||||||
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h2 class="panel-title">Add a Bridge Device for a Vera scene</h2>
|
<h2 class="panel-title">Add a Bridge Device for a Vera scene</h2>
|
||||||
</div>
|
</div>
|
||||||
<ul class="list-group">
|
<div class="panel-body">
|
||||||
<li class="list-group-item">
|
<form class="form-horizontal">
|
||||||
<form class="form-horizontal">
|
<div class="form-group">
|
||||||
<div class="form-group">
|
<label class="col-xs-12 col-sm-2 control-label" for="device-name">Name
|
||||||
<label class="col-xs-12 col-sm-2 control-label" for="device-name">Name
|
</label>
|
||||||
</label>
|
|
||||||
|
|
||||||
<div class="col-xs-8 col-sm-7">
|
<div class="col-xs-8 col-sm-7">
|
||||||
<input type="text" class="form-control" id="device-name"
|
<input type="text" class="form-control" id="device-name"
|
||||||
ng-model="device.name" placeholder="Device Name">
|
ng-model="device.name" placeholder="Device Name">
|
||||||
</div>
|
|
||||||
<button type="submit" class="col-xs-4 col-sm-2 btn btn-primary" ng-click="addDevice()">
|
|
||||||
Add Bridge Device</button>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<button type="submit" class="col-xs-4 col-sm-2 btn btn-primary"
|
||||||
<div class="row">
|
ng-click="addDevice()">Add Bridge Device</button>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="row">
|
||||||
<label class="col-xs-12 col-sm-2 control-label" for="device-on-url">On
|
<label class="col-xs-12 col-sm-2 control-label" for="device-on-url">On
|
||||||
URL </label>
|
URL </label>
|
||||||
|
|
||||||
@@ -113,15 +122,24 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<label class="col-xs-12 col-sm-2 control-label"
|
<label class="col-xs-12 col-sm-2 control-label"
|
||||||
for="device-off-url">Off URL </label>
|
for="device-off-url">Off URL </label>
|
||||||
|
|
||||||
<div class="col-xs-8 col-sm-7">
|
<div class="col-xs-8 col-sm-7">
|
||||||
<textarea rows="3" class="form-control" id="device-off-url"
|
<textarea rows="3" class="form-control" id="device-off-url"
|
||||||
ng-model="device.offUrl" placeholder="URL to turn device off"></textarea>
|
ng-model="device.offUrl" placeholder="URL to turn device off"></textarea>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</form>
|
||||||
</form>
|
</div>
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
|
<script type="text/ng-template" id="deleteMapandIdDialog">
|
||||||
|
<div class="ngdialog-message">
|
||||||
|
<h2>Device Map and Id?</h2>
|
||||||
|
<p>{{mapandid.mapType}} with {{mapandid.id}}</p>
|
||||||
|
<p>Are you Sure?</p>
|
||||||
|
</div>
|
||||||
|
<div class="ngdialog-buttons mt">
|
||||||
|
<button type="button" class="ngdialog-button ngdialog-button-error" ng-click="deleteMapandId(mapandid)">Delete</button>
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
Reference in New Issue
Block a user