mirror of
https://github.com/bwssytems/ha-bridge.git
synced 2025-12-16 18:24:36 +00:00
Added config settings page and refactored backup handling and bridge
settings and cotntrol. Next is to add the editing to the config screen.
This commit is contained in:
2
pom.xml
2
pom.xml
@@ -5,7 +5,7 @@
|
||||
|
||||
<groupId>com.bwssystems.HABridge</groupId>
|
||||
<artifactId>ha-bridge</artifactId>
|
||||
<version>1.3.8b</version>
|
||||
<version>1.3.8c</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>HA Bridge</name>
|
||||
|
||||
@@ -4,19 +4,12 @@ import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.SocketException;
|
||||
import java.nio.file.DirectoryStream;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.http.conn.util.InetAddressUtils;
|
||||
import org.slf4j.Logger;
|
||||
@@ -24,146 +17,139 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
public class BridgeSettings {
|
||||
private String upnpconfigaddress;
|
||||
private String serverport;
|
||||
private String upnpresponseport;
|
||||
private String upnpdevicedb;
|
||||
private IpList veraaddress;
|
||||
private IpList harmonyaddress;
|
||||
private String harmonyuser;
|
||||
private String harmonypwd;
|
||||
private Integer buttonsleep;
|
||||
private boolean upnpstrict;
|
||||
private boolean traceupnp;
|
||||
private boolean devmode;
|
||||
private String nestuser;
|
||||
private String nestpwd;
|
||||
private boolean veraconfigured;
|
||||
private boolean harmonyconfigured;
|
||||
private boolean nestconfigured;
|
||||
private String configfile;
|
||||
private boolean restart;
|
||||
public class BridgeSettings extends BackupHandler {
|
||||
private BridgeSettingsDescriptor theBridgeSettings;
|
||||
private boolean reinit;
|
||||
private boolean stop;
|
||||
|
||||
public BridgeSettings() {
|
||||
super();
|
||||
this.upnpstrict = true;
|
||||
this.devmode = false;
|
||||
this.traceupnp = false;
|
||||
this.restart = false;
|
||||
this.reinit = false;
|
||||
this.stop = false;
|
||||
this.nestconfigured = false;
|
||||
this.veraconfigured = false;
|
||||
this.harmonyconfigured = false;
|
||||
theBridgeSettings = new BridgeSettingsDescriptor();
|
||||
theBridgeSettings.setUpnpStrict(true);
|
||||
theBridgeSettings.setDevMode(false);
|
||||
theBridgeSettings.setTraceupnp(false);
|
||||
theBridgeSettings.setNestConfigured(false);
|
||||
theBridgeSettings.setVeraconfigured(false);
|
||||
theBridgeSettings.setHarmonyconfigured(false);
|
||||
}
|
||||
public BridgeSettingsDescriptor getBridgeSettingsDescriptor() {
|
||||
return theBridgeSettings;
|
||||
}
|
||||
public String getUpnpConfigAddress() {
|
||||
return upnpconfigaddress;
|
||||
return theBridgeSettings.getUpnpConfigAddress();
|
||||
}
|
||||
public void setUpnpConfigAddress(String upnpConfigAddress) {
|
||||
this.upnpconfigaddress = upnpConfigAddress;
|
||||
theBridgeSettings.setUpnpConfigAddress(upnpConfigAddress);
|
||||
}
|
||||
public String getServerPort() {
|
||||
return serverport;
|
||||
return theBridgeSettings.getServerPort();
|
||||
}
|
||||
public void setServerPort(String serverPort) {
|
||||
this.serverport = serverPort;
|
||||
theBridgeSettings.setServerPort(serverPort);
|
||||
}
|
||||
public String getUpnpResponsePort() {
|
||||
return upnpresponseport;
|
||||
return theBridgeSettings.getUpnpResponsePort();
|
||||
}
|
||||
public void setUpnpResponsePort(String upnpResponsePort) {
|
||||
this.upnpresponseport = upnpResponsePort;
|
||||
theBridgeSettings.setUpnpResponsePort(upnpResponsePort);
|
||||
}
|
||||
public String getUpnpDeviceDb() {
|
||||
return upnpdevicedb;
|
||||
return theBridgeSettings.getUpnpDeviceDb();
|
||||
}
|
||||
public void setUpnpDeviceDb(String upnpDeviceDb) {
|
||||
this.upnpdevicedb = upnpDeviceDb;
|
||||
theBridgeSettings.setUpnpDeviceDb(upnpDeviceDb);
|
||||
}
|
||||
public IpList getVeraAddress() {
|
||||
return veraaddress;
|
||||
return theBridgeSettings.getVeraAddress();
|
||||
}
|
||||
public void setVeraAddress(IpList veraAddress) {
|
||||
this.veraaddress = veraAddress;
|
||||
theBridgeSettings.setVeraAddress(veraAddress);
|
||||
}
|
||||
public IpList getHarmonyAddress() {
|
||||
return harmonyaddress;
|
||||
return theBridgeSettings.getHarmonyAddress();
|
||||
}
|
||||
public void setHarmonyAddress(IpList harmonyaddress) {
|
||||
this.harmonyaddress = harmonyaddress;
|
||||
theBridgeSettings.setHarmonyAddress(harmonyaddress);
|
||||
}
|
||||
public String getHarmonyUser() {
|
||||
return harmonyuser;
|
||||
return theBridgeSettings.getHarmonyUser();
|
||||
}
|
||||
public void setHarmonyUser(String harmonyuser) {
|
||||
this.harmonyuser = harmonyuser;
|
||||
theBridgeSettings.setHarmonyUser(harmonyuser);
|
||||
}
|
||||
public String getHarmonyPwd() {
|
||||
return harmonypwd;
|
||||
return theBridgeSettings.getHarmonyPwd();
|
||||
}
|
||||
public void setHarmonyPwd(String harmonypwd) {
|
||||
this.harmonypwd = harmonypwd;
|
||||
theBridgeSettings.setHarmonyPwd(harmonypwd);
|
||||
}
|
||||
public boolean isUpnpStrict() {
|
||||
return upnpstrict;
|
||||
return theBridgeSettings.isUpnpStrict();
|
||||
}
|
||||
public void setUpnpStrict(boolean upnpStrict) {
|
||||
this.upnpstrict = upnpStrict;
|
||||
theBridgeSettings.setUpnpStrict(upnpStrict);
|
||||
}
|
||||
public boolean isTraceupnp() {
|
||||
return traceupnp;
|
||||
return theBridgeSettings.isTraceupnp();
|
||||
}
|
||||
public void setTraceupnp(boolean traceupnp) {
|
||||
this.traceupnp = traceupnp;
|
||||
theBridgeSettings.setTraceupnp(traceupnp);
|
||||
}
|
||||
public boolean isDevMode() {
|
||||
return devmode;
|
||||
return theBridgeSettings.isDevMode();
|
||||
}
|
||||
public void setDevMode(boolean devmode) {
|
||||
this.devmode = devmode;
|
||||
theBridgeSettings.setDevMode(devmode);
|
||||
}
|
||||
public String getNestuser() {
|
||||
return nestuser;
|
||||
return theBridgeSettings.getNestuser();
|
||||
}
|
||||
public void setNestuser(String nestuser) {
|
||||
this.nestuser = nestuser;
|
||||
theBridgeSettings.setNestuser(nestuser);
|
||||
}
|
||||
public String getNestpwd() {
|
||||
return nestpwd;
|
||||
return theBridgeSettings.getNestpwd();
|
||||
}
|
||||
public void setNestpwd(String nestpwd) {
|
||||
this.nestpwd = nestpwd;
|
||||
theBridgeSettings.setNestpwd(nestpwd);
|
||||
}
|
||||
public boolean isVeraconfigured() {
|
||||
return veraconfigured;
|
||||
return theBridgeSettings.isVeraconfigured();
|
||||
}
|
||||
public void setVeraconfigured(boolean veraconfigured) {
|
||||
this.veraconfigured = veraconfigured;
|
||||
theBridgeSettings.setVeraconfigured(veraconfigured);
|
||||
}
|
||||
public boolean isHarmonyconfigured() {
|
||||
return harmonyconfigured;
|
||||
return theBridgeSettings.isHarmonyconfigured();
|
||||
}
|
||||
public void setHarmonyconfigured(boolean harmonyconfigured) {
|
||||
this.harmonyconfigured = harmonyconfigured;
|
||||
theBridgeSettings.setHarmonyconfigured(harmonyconfigured);
|
||||
}
|
||||
public boolean isNestConfigured() {
|
||||
return nestconfigured;
|
||||
return theBridgeSettings.isNestConfigured();
|
||||
}
|
||||
public void setNestConfigured(boolean isNestConfigured) {
|
||||
this.nestconfigured = isNestConfigured;
|
||||
theBridgeSettings.setNestConfigured(isNestConfigured);
|
||||
}
|
||||
public Integer getButtonsleep() {
|
||||
return buttonsleep;
|
||||
return theBridgeSettings.getButtonsleep();
|
||||
}
|
||||
public void setButtonsleep(Integer buttonsleep) {
|
||||
this.buttonsleep = buttonsleep;
|
||||
theBridgeSettings.setButtonsleep(buttonsleep);
|
||||
}
|
||||
public boolean isRestart() {
|
||||
return restart;
|
||||
public String getConfigfile() {
|
||||
return theBridgeSettings.getConfigfile();
|
||||
}
|
||||
public void setRestart(boolean restart) {
|
||||
this.restart = restart;
|
||||
public void setConfigfile(String configfile) {
|
||||
theBridgeSettings.setConfigfile(configfile);
|
||||
}
|
||||
public boolean isReinit() {
|
||||
return reinit;
|
||||
}
|
||||
public void setReinit(boolean reinit) {
|
||||
this.reinit = reinit;
|
||||
}
|
||||
public boolean isStop() {
|
||||
return stop;
|
||||
@@ -171,39 +157,6 @@ public class BridgeSettings {
|
||||
public void setStop(boolean stop) {
|
||||
this.stop = stop;
|
||||
}
|
||||
public String getConfigfile() {
|
||||
return configfile;
|
||||
}
|
||||
public void setConfigfile(String configfile) {
|
||||
this.configfile = configfile;
|
||||
}
|
||||
public Boolean isValidVera() {
|
||||
if(this.veraaddress == null)
|
||||
return false;
|
||||
List<NamedIP> devicesList = this.veraaddress.getDevices();
|
||||
if(devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
public Boolean isValidHarmony() {
|
||||
if(this.harmonyaddress == null)
|
||||
return false;
|
||||
List<NamedIP> devicesList = this.harmonyaddress.getDevices();
|
||||
if(devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS))
|
||||
return false; if(this.harmonypwd == null || this.harmonypwd == "")
|
||||
return false;
|
||||
if(this.harmonyuser == null || this.harmonyuser == "")
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
public Boolean isValidNest() {
|
||||
if(this.nestpwd == null || this.nestpwd == "")
|
||||
return false;
|
||||
if(this.nestuser == null || this.nestuser == "")
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void buildSettings() {
|
||||
Logger log = LoggerFactory.getLogger(BridgeSettings.class);
|
||||
InetAddress address = null;
|
||||
@@ -314,8 +267,17 @@ public class BridgeSettings {
|
||||
|
||||
if(this.getButtonsleep() <= 0)
|
||||
this.setButtonsleep(Integer.parseInt(Configuration.DFAULT_BUTTON_SLEEP));
|
||||
|
||||
this.setVeraconfigured(theBridgeSettings.isValidVera());
|
||||
this.setHarmonyconfigured(theBridgeSettings.isValidHarmony());
|
||||
this.setNestConfigured(theBridgeSettings.isValidNest());
|
||||
setupParams(Paths.get(getConfigfile()), ".cfgbk", "habridge.config-");
|
||||
}
|
||||
|
||||
public void loadConfig() {
|
||||
if(getConfigfile() != null)
|
||||
_loadConfig();
|
||||
}
|
||||
private void _loadConfig() {
|
||||
Path configPath = Paths.get(getConfigfile());
|
||||
_loadConfig(configPath);
|
||||
@@ -323,7 +285,7 @@ public class BridgeSettings {
|
||||
|
||||
private void _loadConfig(Path aPath) {
|
||||
String jsonContent = configReader(aPath);
|
||||
BridgeSettings aBridgeSettings = new Gson().fromJson(jsonContent, BridgeSettings.class);
|
||||
BridgeSettingsDescriptor aBridgeSettings = new Gson().fromJson(jsonContent, BridgeSettingsDescriptor.class);
|
||||
this.setButtonsleep(aBridgeSettings.getButtonsleep());
|
||||
this.setUpnpConfigAddress(aBridgeSettings.getUpnpConfigAddress());
|
||||
this.setServerPort(aBridgeSettings.getServerPort());
|
||||
@@ -338,18 +300,19 @@ public class BridgeSettings {
|
||||
this.setDevMode(aBridgeSettings.isDevMode());
|
||||
this.setNestuser(aBridgeSettings.getNestuser());
|
||||
this.setNestpwd(aBridgeSettings.getNestpwd());
|
||||
this.setVeraconfigured(aBridgeSettings.isVeraconfigured());
|
||||
this.setHarmonyconfigured(aBridgeSettings.isHarmonyconfigured());
|
||||
this.setNestConfigured(aBridgeSettings.isNestConfigured());
|
||||
this.setVeraconfigured(aBridgeSettings.isValidVera());
|
||||
this.setHarmonyconfigured(aBridgeSettings.isValidHarmony());
|
||||
this.setNestConfigured(aBridgeSettings.isValidNest());
|
||||
}
|
||||
|
||||
public void save() {
|
||||
public void save(BridgeSettings newBridgeSettings) {
|
||||
Logger log = LoggerFactory.getLogger(BridgeSettings.class);
|
||||
log.debug("Save HA Bridge settings.");
|
||||
Path configPath = Paths.get(getConfigfile());
|
||||
JsonTransformer aRenderer = new JsonTransformer();
|
||||
String jsonValue = aRenderer.render(this);
|
||||
String jsonValue = aRenderer.render(newBridgeSettings);
|
||||
configWriter(jsonValue, configPath);
|
||||
log.debug("Save HA Bridge settings.");
|
||||
_loadConfig(configPath);
|
||||
}
|
||||
|
||||
|
||||
@@ -371,7 +334,7 @@ public class BridgeSettings {
|
||||
try {
|
||||
Path target = null;
|
||||
if(Files.exists(filePath)) {
|
||||
target = FileSystems.getDefault().getPath(filePath.getParent().toString(), "device.db.old");
|
||||
target = FileSystems.getDefault().getPath(filePath.getParent().toString(), "habridge.config.old");
|
||||
Files.move(filePath, target);
|
||||
}
|
||||
Files.write(filePath, content.getBytes(), StandardOpenOption.CREATE);
|
||||
@@ -400,72 +363,4 @@ public class BridgeSettings {
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
public String backupConfig(String aFilename) {
|
||||
Logger log = LoggerFactory.getLogger(BridgeSettings.class);
|
||||
Path configPath = Paths.get(getConfigfile());
|
||||
if(aFilename == null || aFilename.equalsIgnoreCase("")) {
|
||||
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
|
||||
aFilename = "habridge.config-" + dateFormat.format(Calendar.getInstance().getTime()) + ".bk";
|
||||
}
|
||||
else
|
||||
aFilename = aFilename + ".bk";
|
||||
try {
|
||||
Files.copy(configPath, FileSystems.getDefault().getPath(configPath.getParent().toString(), aFilename), StandardCopyOption.COPY_ATTRIBUTES);
|
||||
} catch (IOException e) {
|
||||
log.error("Could not backup to file: " + aFilename + " message: " + e.getMessage(), e);
|
||||
}
|
||||
log.debug("Backup config: " + aFilename);
|
||||
return aFilename;
|
||||
}
|
||||
|
||||
public String deleteConfigBackup(String aFilename) {
|
||||
Logger log = LoggerFactory.getLogger(BridgeSettings.class);
|
||||
Path configPath = Paths.get(getConfigfile());
|
||||
log.debug("Delete backup config: " + aFilename);
|
||||
try {
|
||||
Files.delete(FileSystems.getDefault().getPath(configPath.getParent().toString(), aFilename));
|
||||
} catch (IOException e) {
|
||||
log.error("Could not delete file: " + aFilename + " message: " + e.getMessage(), e);
|
||||
}
|
||||
return aFilename;
|
||||
}
|
||||
|
||||
public String restoreConfigBackup(String aFilename) {
|
||||
Logger log = LoggerFactory.getLogger(BridgeSettings.class);
|
||||
Path configPath = Paths.get(getConfigfile());
|
||||
log.debug("Restore backup config: " + aFilename);
|
||||
try {
|
||||
Path target = null;
|
||||
if(Files.exists(configPath)) {
|
||||
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
|
||||
target = FileSystems.getDefault().getPath(configPath.getParent().toString(), "habridge.config-" + dateFormat.format(Calendar.getInstance().getTime()) + ".bk");
|
||||
Files.move(configPath, target);
|
||||
}
|
||||
Files.copy(FileSystems.getDefault().getPath(configPath.getParent().toString(), aFilename), configPath, StandardCopyOption.COPY_ATTRIBUTES);
|
||||
} catch (IOException e) {
|
||||
log.error("Error restoring the file: " + aFilename + " message: " + e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
_loadConfig(configPath);
|
||||
return aFilename;
|
||||
}
|
||||
|
||||
public List<String> getConfigBackups() {
|
||||
Logger log = LoggerFactory.getLogger(BridgeSettings.class);
|
||||
Path configPath = Paths.get(getConfigfile());
|
||||
List<String> theFilenames = new ArrayList<String>();
|
||||
Path dir = configPath.getParent();
|
||||
try (DirectoryStream<Path> stream =
|
||||
Files.newDirectoryStream(dir, "*.{bk}")) {
|
||||
for (Path entry: stream) {
|
||||
theFilenames.add(entry.getFileName().toString());
|
||||
}
|
||||
} catch (IOException x) {
|
||||
// IOException can never be thrown by the iteration.
|
||||
// In this snippet, it can // only be thrown by newDirectoryStream.
|
||||
log.error("Issue getting directory listing for config backups - " + x.getMessage());
|
||||
}
|
||||
return theFilenames;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
package com.bwssystems.HABridge;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class BridgeSettingsDescriptor {
|
||||
private String upnpconfigaddress;
|
||||
private String serverport;
|
||||
private String upnpresponseport;
|
||||
private String upnpdevicedb;
|
||||
private IpList veraaddress;
|
||||
private IpList harmonyaddress;
|
||||
private String harmonyuser;
|
||||
private String harmonypwd;
|
||||
private Integer buttonsleep;
|
||||
private boolean upnpstrict;
|
||||
private boolean traceupnp;
|
||||
private boolean devmode;
|
||||
private String nestuser;
|
||||
private String nestpwd;
|
||||
private boolean veraconfigured;
|
||||
private boolean harmonyconfigured;
|
||||
private boolean nestconfigured;
|
||||
private String configfile;
|
||||
|
||||
public BridgeSettingsDescriptor() {
|
||||
super();
|
||||
this.upnpstrict = true;
|
||||
this.devmode = false;
|
||||
this.traceupnp = false;
|
||||
this.nestconfigured = false;
|
||||
this.veraconfigured = false;
|
||||
this.harmonyconfigured = false;
|
||||
}
|
||||
public String getUpnpConfigAddress() {
|
||||
return upnpconfigaddress;
|
||||
}
|
||||
public void setUpnpConfigAddress(String upnpConfigAddress) {
|
||||
this.upnpconfigaddress = upnpConfigAddress;
|
||||
}
|
||||
public String getServerPort() {
|
||||
return serverport;
|
||||
}
|
||||
public void setServerPort(String serverPort) {
|
||||
this.serverport = serverPort;
|
||||
}
|
||||
public String getUpnpResponsePort() {
|
||||
return upnpresponseport;
|
||||
}
|
||||
public void setUpnpResponsePort(String upnpResponsePort) {
|
||||
this.upnpresponseport = upnpResponsePort;
|
||||
}
|
||||
public String getUpnpDeviceDb() {
|
||||
return upnpdevicedb;
|
||||
}
|
||||
public void setUpnpDeviceDb(String upnpDeviceDb) {
|
||||
this.upnpdevicedb = upnpDeviceDb;
|
||||
}
|
||||
public IpList getVeraAddress() {
|
||||
return veraaddress;
|
||||
}
|
||||
public void setVeraAddress(IpList veraAddress) {
|
||||
this.veraaddress = veraAddress;
|
||||
}
|
||||
public IpList getHarmonyAddress() {
|
||||
return harmonyaddress;
|
||||
}
|
||||
public void setHarmonyAddress(IpList harmonyaddress) {
|
||||
this.harmonyaddress = harmonyaddress;
|
||||
}
|
||||
public String getHarmonyUser() {
|
||||
return harmonyuser;
|
||||
}
|
||||
public void setHarmonyUser(String harmonyuser) {
|
||||
this.harmonyuser = harmonyuser;
|
||||
}
|
||||
public String getHarmonyPwd() {
|
||||
return harmonypwd;
|
||||
}
|
||||
public void setHarmonyPwd(String harmonypwd) {
|
||||
this.harmonypwd = harmonypwd;
|
||||
}
|
||||
public boolean isUpnpStrict() {
|
||||
return upnpstrict;
|
||||
}
|
||||
public void setUpnpStrict(boolean upnpStrict) {
|
||||
this.upnpstrict = upnpStrict;
|
||||
}
|
||||
public boolean isTraceupnp() {
|
||||
return traceupnp;
|
||||
}
|
||||
public void setTraceupnp(boolean traceupnp) {
|
||||
this.traceupnp = traceupnp;
|
||||
}
|
||||
public boolean isDevMode() {
|
||||
return devmode;
|
||||
}
|
||||
public void setDevMode(boolean devmode) {
|
||||
this.devmode = devmode;
|
||||
}
|
||||
public String getNestuser() {
|
||||
return nestuser;
|
||||
}
|
||||
public void setNestuser(String nestuser) {
|
||||
this.nestuser = nestuser;
|
||||
}
|
||||
public String getNestpwd() {
|
||||
return nestpwd;
|
||||
}
|
||||
public void setNestpwd(String nestpwd) {
|
||||
this.nestpwd = nestpwd;
|
||||
}
|
||||
public boolean isVeraconfigured() {
|
||||
return veraconfigured;
|
||||
}
|
||||
public void setVeraconfigured(boolean veraconfigured) {
|
||||
this.veraconfigured = veraconfigured;
|
||||
}
|
||||
public boolean isHarmonyconfigured() {
|
||||
return harmonyconfigured;
|
||||
}
|
||||
public void setHarmonyconfigured(boolean harmonyconfigured) {
|
||||
this.harmonyconfigured = harmonyconfigured;
|
||||
}
|
||||
public boolean isNestConfigured() {
|
||||
return nestconfigured;
|
||||
}
|
||||
public void setNestConfigured(boolean isNestConfigured) {
|
||||
this.nestconfigured = isNestConfigured;
|
||||
}
|
||||
public Integer getButtonsleep() {
|
||||
return buttonsleep;
|
||||
}
|
||||
public void setButtonsleep(Integer buttonsleep) {
|
||||
this.buttonsleep = buttonsleep;
|
||||
}
|
||||
public String getConfigfile() {
|
||||
return configfile;
|
||||
}
|
||||
public void setConfigfile(String configfile) {
|
||||
this.configfile = configfile;
|
||||
}
|
||||
public Boolean isValidVera() {
|
||||
if(this.getVeraAddress() == null)
|
||||
return false;
|
||||
List<NamedIP> devicesList = this.getVeraAddress().getDevices();
|
||||
if(devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
public Boolean isValidHarmony() {
|
||||
if(this.getHarmonyAddress() == null)
|
||||
return false;
|
||||
List<NamedIP> devicesList = this.getHarmonyAddress().getDevices();
|
||||
if(devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS))
|
||||
return false;
|
||||
if(this.getHarmonyPwd() == null || this.getHarmonyPwd() == "")
|
||||
return false;
|
||||
if(this.getHarmonyUser() == null || this.getHarmonyUser() == "")
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
public Boolean isValidNest() {
|
||||
if(this.getNestpwd() == null || this.getNestpwd() == "")
|
||||
return false;
|
||||
if(this.getNestuser() == null || this.getNestuser() == "")
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,9 +7,6 @@ public class Configuration {
|
||||
public final static String DEFAULT_ADDRESS = "1.1.1.1";
|
||||
public final static String LOOP_BACK_ADDRESS = "127.0.0.1";
|
||||
public final static String LOOP_BACK_INTERFACE = "lo";
|
||||
public final static String DEFAULT_HARMONY_ADDRESS_LIST = "{devices:[{name:default,ip:1.1.1.1}]}";
|
||||
public final static String DEFAULT_USER = "";
|
||||
public final static String DEFAULT_PWD = "";
|
||||
public final static String DFAULT_WEB_PORT = "8080";
|
||||
public final static String DFAULT_BUTTON_SLEEP = "100";
|
||||
public static final int UPNP_DISCOVERY_PORT = 1900;
|
||||
|
||||
@@ -37,6 +37,7 @@ public class HABridge {
|
||||
HueMulator theHueMulator;
|
||||
UpnpSettingsResource theSettingResponder;
|
||||
UpnpListener theUpnpListener;
|
||||
SystemControl theSystem;
|
||||
BridgeSettings bridgeSettings;
|
||||
Version theVersion;
|
||||
|
||||
@@ -45,7 +46,7 @@ public class HABridge {
|
||||
log.info("HA Bridge (v" + theVersion.getVersion() + ") starting....");
|
||||
|
||||
bridgeSettings = new BridgeSettings();
|
||||
bridgeSettings.setRestart(false);
|
||||
bridgeSettings.setReinit(false);
|
||||
bridgeSettings.setStop(false);
|
||||
while(!bridgeSettings.isStop()) {
|
||||
bridgeSettings.buildSettings();
|
||||
@@ -56,17 +57,20 @@ public class HABridge {
|
||||
port(Integer.valueOf(bridgeSettings.getServerPort()));
|
||||
// sparkjava config directive to set html static file location for Jetty
|
||||
staticFileLocation("/public");
|
||||
// setup system control api first
|
||||
theSystem = new SystemControl(bridgeSettings, theVersion);
|
||||
theSystem.setupServer();
|
||||
//setup the harmony connection if available
|
||||
harmonyHome = new HarmonyHome(bridgeSettings);
|
||||
harmonyHome = new HarmonyHome(bridgeSettings.getBridgeSettingsDescriptor());
|
||||
//setup the nest connection if available
|
||||
nestHome = new NestHome(bridgeSettings);
|
||||
nestHome = new NestHome(bridgeSettings.getBridgeSettingsDescriptor());
|
||||
// setup the class to handle the resource setup rest api
|
||||
theResources = new DeviceResource(bridgeSettings, theVersion, harmonyHome, nestHome);
|
||||
theResources = new DeviceResource(bridgeSettings.getBridgeSettingsDescriptor(), harmonyHome, nestHome);
|
||||
// setup the class to handle the hue emulator rest api
|
||||
theHueMulator = new HueMulator(bridgeSettings, theResources.getDeviceRepository(), harmonyHome, nestHome);
|
||||
theHueMulator = new HueMulator(bridgeSettings.getBridgeSettingsDescriptor(), theResources.getDeviceRepository(), harmonyHome, nestHome);
|
||||
theHueMulator.setupServer();
|
||||
// setup the class to handle the upnp response rest api
|
||||
theSettingResponder = new UpnpSettingsResource(bridgeSettings);
|
||||
theSettingResponder = new UpnpSettingsResource(bridgeSettings.getBridgeSettingsDescriptor());
|
||||
theSettingResponder.setupServer();
|
||||
// wait for the sparkjava initialization of the rest api classes to be complete
|
||||
awaitInitialization();
|
||||
@@ -76,7 +80,7 @@ public class HABridge {
|
||||
if(theUpnpListener.startListening())
|
||||
log.info("HA Bridge (v" + theVersion.getVersion() + ") reinitialization requessted....");
|
||||
|
||||
bridgeSettings.setRestart(false);
|
||||
bridgeSettings.setReinit(false);
|
||||
stop();
|
||||
}
|
||||
log.info("HA Bridge (v" + theVersion.getVersion() + ") exiting....");
|
||||
|
||||
173
src/main/java/com/bwssystems/HABridge/SystemControl.java
Normal file
173
src/main/java/com/bwssystems/HABridge/SystemControl.java
Normal file
@@ -0,0 +1,173 @@
|
||||
package com.bwssystems.HABridge;
|
||||
|
||||
import static spark.Spark.get;
|
||||
import static spark.Spark.options;
|
||||
import static spark.Spark.post;
|
||||
import static spark.Spark.put;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.InetAddress;
|
||||
import java.net.MulticastSocket;
|
||||
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.bwssystems.HABridge.dao.BackupFilename;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
public class SystemControl {
|
||||
private static final Logger log = LoggerFactory.getLogger(SystemControl.class);
|
||||
private static final String SYSTEM_CONTEXT = "/system";
|
||||
private BridgeSettings bridgeSettings;
|
||||
private Version version;
|
||||
|
||||
public SystemControl(BridgeSettings theBridgeSettings, Version theVersion) {
|
||||
this.bridgeSettings = theBridgeSettings;
|
||||
this.version = theVersion;
|
||||
}
|
||||
|
||||
// This function sets up the sparkjava rest calls for the hue api
|
||||
public void setupServer() {
|
||||
log.info("Hue emulator service started....");
|
||||
// http://ip_address:port/system/habridge/version gets the version of this bridge instance
|
||||
get (SYSTEM_CONTEXT + "/habridge/version", "application/json", (request, response) -> {
|
||||
log.debug("Get HA Bridge version: v" + version.getVersion());
|
||||
response.status(HttpStatus.SC_OK);
|
||||
return "{\"version\":\"" + version.getVersion() + "\"}";
|
||||
});
|
||||
|
||||
// http://ip_address:port/system/settings which returns the bridge configuration settings
|
||||
get(SYSTEM_CONTEXT + "/settings", "application/json", (request, response) -> {
|
||||
log.debug("bridge settings requested from " + request.ip());
|
||||
|
||||
response.status(200);
|
||||
|
||||
return bridgeSettings;
|
||||
}, new JsonTransformer());
|
||||
|
||||
// http://ip_address:port/system/control/reinit CORS request
|
||||
options(SYSTEM_CONTEXT + "/control/reinit", "application/json", (request, response) -> {
|
||||
response.status(HttpStatus.SC_OK);
|
||||
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
|
||||
response.header("Access-Control-Allow-Methods", "GET, POST, PUT");
|
||||
response.header("Access-Control-Allow-Headers", request.headers("Access-Control-Request-Headers"));
|
||||
response.header("Content-Type", "text/html; charset=utf-8");
|
||||
return "";
|
||||
});
|
||||
// http://ip_address:port/system/control/reinit sets the parameter reinit the server
|
||||
put(SYSTEM_CONTEXT + "/control/reinit", "application/json", (request, response) -> {
|
||||
return reinit();
|
||||
});
|
||||
|
||||
// http://ip_address:port/system/control/stop CORS request
|
||||
options(SYSTEM_CONTEXT + "/control/stop", "application/json", (request, response) -> {
|
||||
response.status(HttpStatus.SC_OK);
|
||||
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
|
||||
response.header("Access-Control-Allow-Methods", "GET, POST, PUT");
|
||||
response.header("Access-Control-Allow-Headers", request.headers("Access-Control-Request-Headers"));
|
||||
response.header("Content-Type", "text/html; charset=utf-8");
|
||||
return "";
|
||||
});
|
||||
// http://ip_address:port/system/control/stop sets the parameter stop the server
|
||||
put(SYSTEM_CONTEXT + "/control/stop", "application/json", (request, response) -> {
|
||||
return stop();
|
||||
});
|
||||
|
||||
// http://ip_address:port/system/backup/available returns a list of config backup filenames
|
||||
get (SYSTEM_CONTEXT + "/backup/available", "application/json", (request, response) -> {
|
||||
log.debug("Get backup filenames");
|
||||
response.status(HttpStatus.SC_OK);
|
||||
return bridgeSettings.getBackups();
|
||||
}, new JsonTransformer());
|
||||
|
||||
// http://ip_address:port/system/backup/create CORS request
|
||||
options(SYSTEM_CONTEXT + "/backup/create", "application/json", (request, response) -> {
|
||||
response.status(HttpStatus.SC_OK);
|
||||
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
|
||||
response.header("Access-Control-Allow-Methods", "PUT");
|
||||
response.header("Access-Control-Allow-Headers", request.headers("Access-Control-Request-Headers"));
|
||||
response.header("Content-Type", "text/html; charset=utf-8");
|
||||
return "";
|
||||
});
|
||||
put (SYSTEM_CONTEXT + "/backup/create", "application/json", (request, response) -> {
|
||||
log.debug("Create backup: " + request.body());
|
||||
BackupFilename aFilename = new Gson().fromJson(request.body(), BackupFilename.class);
|
||||
BackupFilename returnFilename = new BackupFilename();
|
||||
returnFilename.setFilename(bridgeSettings.backup(aFilename.getFilename()));
|
||||
return returnFilename;
|
||||
}, new JsonTransformer());
|
||||
|
||||
// http://ip_address:port/system/backup/delete CORS request
|
||||
options(SYSTEM_CONTEXT + "/backup/delete", "application/json", (request, response) -> {
|
||||
response.status(HttpStatus.SC_OK);
|
||||
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
|
||||
response.header("Access-Control-Allow-Methods", "POST");
|
||||
response.header("Access-Control-Allow-Headers", request.headers("Access-Control-Request-Headers"));
|
||||
response.header("Content-Type", "text/html; charset=utf-8");
|
||||
return "";
|
||||
});
|
||||
post (SYSTEM_CONTEXT + "/backup/delete", "application/json", (request, response) -> {
|
||||
log.debug("Delete backup: " + request.body());
|
||||
BackupFilename aFilename = new Gson().fromJson(request.body(), BackupFilename.class);
|
||||
if(aFilename != null)
|
||||
bridgeSettings.deleteBackup(aFilename.getFilename());
|
||||
else
|
||||
log.warn("No filename given for delete backup.");
|
||||
return null;
|
||||
}, new JsonTransformer());
|
||||
|
||||
// http://ip_address:port/system/backup/restore CORS request
|
||||
options(SYSTEM_CONTEXT + "/backup/restore", "application/json", (request, response) -> {
|
||||
response.status(HttpStatus.SC_OK);
|
||||
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
|
||||
response.header("Access-Control-Allow-Methods", "POST");
|
||||
response.header("Access-Control-Allow-Headers", request.headers("Access-Control-Request-Headers"));
|
||||
response.header("Content-Type", "text/html; charset=utf-8");
|
||||
return "";
|
||||
});
|
||||
post (SYSTEM_CONTEXT + "/backup/restore", "application/json", (request, response) -> {
|
||||
log.debug("Restore backup: " + request.body());
|
||||
BackupFilename aFilename = new Gson().fromJson(request.body(), BackupFilename.class);
|
||||
if(aFilename != null) {
|
||||
bridgeSettings.restoreBackup(aFilename.getFilename());
|
||||
bridgeSettings.loadConfig();
|
||||
}
|
||||
else
|
||||
log.warn("No filename given for restore backup.");
|
||||
return null;
|
||||
}, new JsonTransformer());
|
||||
}
|
||||
|
||||
protected void pingListener() {
|
||||
try {
|
||||
byte[] buf = new byte[256];
|
||||
String testData = "M-SEARCH * HTTP/1.1\nHOST: " + Configuration.UPNP_MULTICAST_ADDRESS + ":" + Configuration.UPNP_DISCOVERY_PORT + "ST: urn:schemas-upnp-org:device:CloudProxy:1\nMAN: \"ssdp:discover\"\nMX: 3";
|
||||
buf = testData.getBytes();
|
||||
MulticastSocket socket = new MulticastSocket(Configuration.UPNP_DISCOVERY_PORT);
|
||||
|
||||
InetAddress group = InetAddress.getByName(Configuration.UPNP_MULTICAST_ADDRESS);
|
||||
DatagramPacket packet;
|
||||
packet = new DatagramPacket(buf, buf.length, group, Configuration.UPNP_DISCOVERY_PORT);
|
||||
socket.send(packet);
|
||||
|
||||
socket.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
log.warn("Error pinging listener.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public String reinit() {
|
||||
bridgeSettings.setReinit(true);
|
||||
pingListener();
|
||||
return "{\"control\":\"reiniting\"}";
|
||||
}
|
||||
|
||||
public String stop() {
|
||||
bridgeSettings.setStop(true);
|
||||
pingListener();
|
||||
return "{\"control\":\"stopping\"}";
|
||||
}
|
||||
}
|
||||
@@ -3,23 +3,19 @@ package com.bwssystems.HABridge.dao;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.nio.file.DirectoryStream;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.bwssystems.HABridge.BackupHandler;
|
||||
import com.bwssystems.HABridge.JsonTransformer;
|
||||
import com.bwssystems.HABridge.dao.DeviceDescriptor;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
@@ -30,7 +26,7 @@ import java.util.ListIterator;
|
||||
* This is an in memory list to manage the configured devices and saves the list as a JSON string to a file for later
|
||||
* loading.
|
||||
*/
|
||||
public class DeviceRepository {
|
||||
public class DeviceRepository extends BackupHandler {
|
||||
Map<String, DeviceDescriptor> devices;
|
||||
Path repositoryPath;
|
||||
final Random random = new Random();
|
||||
@@ -38,14 +34,16 @@ public class DeviceRepository {
|
||||
|
||||
public DeviceRepository(String deviceDb) {
|
||||
super();
|
||||
_loadRepository(deviceDb);
|
||||
repositoryPath = null;
|
||||
repositoryPath = Paths.get(deviceDb);
|
||||
setupParams(repositoryPath, ".bk", "device.db-");
|
||||
_loadRepository(repositoryPath);
|
||||
}
|
||||
|
||||
private void _loadRepository(String aFilePath){
|
||||
repositoryPath = Paths.get(aFilePath);
|
||||
_loadRepository(repositoryPath);
|
||||
public void loadRepository() {
|
||||
if(repositoryPath != null)
|
||||
_loadRepository(repositoryPath);
|
||||
}
|
||||
|
||||
private void _loadRepository(Path aPath){
|
||||
String jsonContent = repositoryReader(aPath);
|
||||
devices = new HashMap<String, DeviceDescriptor>();
|
||||
@@ -93,66 +91,6 @@ public class DeviceRepository {
|
||||
log.debug("Save device: " + aDescriptor.getName());
|
||||
}
|
||||
|
||||
public String backup(String aFilename) {
|
||||
if(aFilename == null || aFilename.equalsIgnoreCase("")) {
|
||||
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
|
||||
aFilename = "devicedb-" + dateFormat.format(Calendar.getInstance().getTime()) + ".bk";
|
||||
}
|
||||
else
|
||||
aFilename = aFilename + ".bk";
|
||||
try {
|
||||
Files.copy(repositoryPath, FileSystems.getDefault().getPath(repositoryPath.getParent().toString(), aFilename), StandardCopyOption.COPY_ATTRIBUTES);
|
||||
} catch (IOException e) {
|
||||
log.error("Could not backup to file: " + aFilename + " message: " + e.getMessage(), e);
|
||||
}
|
||||
log.debug("Backup repository: " + aFilename);
|
||||
return aFilename;
|
||||
}
|
||||
|
||||
public String deleteBackup(String aFilename) {
|
||||
log.debug("Delete backup repository: " + aFilename);
|
||||
try {
|
||||
Files.delete(FileSystems.getDefault().getPath(repositoryPath.getParent().toString(), aFilename));
|
||||
} catch (IOException e) {
|
||||
log.error("Could not delete file: " + aFilename + " message: " + e.getMessage(), e);
|
||||
}
|
||||
return aFilename;
|
||||
}
|
||||
|
||||
public String restoreBackup(String aFilename) {
|
||||
log.debug("Restore backup repository: " + aFilename);
|
||||
try {
|
||||
Path target = null;
|
||||
if(Files.exists(repositoryPath)) {
|
||||
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
|
||||
target = FileSystems.getDefault().getPath(repositoryPath.getParent().toString(), "devicedb-" + dateFormat.format(Calendar.getInstance().getTime()) + ".bk");
|
||||
Files.move(repositoryPath, target);
|
||||
}
|
||||
Files.copy(FileSystems.getDefault().getPath(repositoryPath.getParent().toString(), aFilename), repositoryPath, StandardCopyOption.COPY_ATTRIBUTES);
|
||||
} catch (IOException e) {
|
||||
log.error("Error restoring the file: " + aFilename + " message: " + e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
_loadRepository(repositoryPath);
|
||||
return aFilename;
|
||||
}
|
||||
|
||||
public List<String> getBackups() {
|
||||
List<String> theFilenames = new ArrayList<String>();
|
||||
Path dir = repositoryPath.getParent();
|
||||
try (DirectoryStream<Path> stream =
|
||||
Files.newDirectoryStream(dir, "*.{bk}")) {
|
||||
for (Path entry: stream) {
|
||||
theFilenames.add(entry.getFileName().toString());
|
||||
}
|
||||
} catch (IOException x) {
|
||||
// IOException can never be thrown by the iteration.
|
||||
// In this snippet, it can // only be thrown by newDirectoryStream.
|
||||
log.error("Issue getting direcotyr listing for backups - " + x.getMessage());
|
||||
}
|
||||
return theFilenames;
|
||||
}
|
||||
|
||||
public String delete(DeviceDescriptor aDescriptor) {
|
||||
if (aDescriptor != null) {
|
||||
devices.remove(aDescriptor.getId());
|
||||
|
||||
@@ -16,8 +16,8 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.bwssystems.HABridge.BridgeSettings;
|
||||
import com.bwssystems.HABridge.BridgeSettingsDescriptor;
|
||||
import com.bwssystems.HABridge.JsonTransformer;
|
||||
import com.bwssystems.HABridge.Version;
|
||||
import com.bwssystems.HABridge.dao.BackupFilename;
|
||||
import com.bwssystems.HABridge.dao.DeviceDescriptor;
|
||||
import com.bwssystems.HABridge.dao.DeviceRepository;
|
||||
@@ -35,12 +35,11 @@ public class DeviceResource {
|
||||
|
||||
private DeviceRepository deviceRepository;
|
||||
private VeraHome veraHome;
|
||||
private Version version;
|
||||
private HarmonyHome myHarmonyHome;
|
||||
private NestHome nestHome;
|
||||
private static final Set<String> supportedVerbs = new HashSet<>(Arrays.asList("get", "put", "post"));
|
||||
|
||||
public DeviceResource(BridgeSettings theSettings, Version theVersion, HarmonyHome theHarmonyHome, NestHome aNestHome) {
|
||||
public DeviceResource(BridgeSettingsDescriptor theSettings, HarmonyHome theHarmonyHome, NestHome aNestHome) {
|
||||
this.deviceRepository = new DeviceRepository(theSettings.getUpnpDeviceDb());
|
||||
|
||||
if(theSettings.isValidVera())
|
||||
@@ -58,7 +57,6 @@ public class DeviceResource {
|
||||
else
|
||||
this.nestHome = null;
|
||||
|
||||
this.version = theVersion;
|
||||
setupEndpoints();
|
||||
}
|
||||
|
||||
@@ -172,12 +170,6 @@ public class DeviceResource {
|
||||
return null;
|
||||
}, new JsonTransformer());
|
||||
|
||||
get (API_CONTEXT + "/habridge/version", "application/json", (request, response) -> {
|
||||
log.debug("Get HA Bridge version: v" + version.getVersion());
|
||||
response.status(HttpStatus.SC_OK);
|
||||
return "{\"version\":\"" + version.getVersion() + "\"}";
|
||||
});
|
||||
|
||||
get (API_CONTEXT + "/vera/devices", "application/json", (request, response) -> {
|
||||
log.debug("Get vera devices");
|
||||
if(veraHome == null){
|
||||
@@ -293,8 +285,10 @@ public class DeviceResource {
|
||||
post (API_CONTEXT + "/backup/restore", "application/json", (request, response) -> {
|
||||
log.debug("Restore backup: " + request.body());
|
||||
BackupFilename aFilename = new Gson().fromJson(request.body(), BackupFilename.class);
|
||||
if(aFilename != null)
|
||||
if(aFilename != null) {
|
||||
deviceRepository.restoreBackup(aFilename.getFilename());
|
||||
deviceRepository.loadRepository();
|
||||
}
|
||||
else
|
||||
log.warn("No filename given for restore backup.");
|
||||
return null;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.bwssystems.HABridge.hue;
|
||||
|
||||
import com.bwssystems.HABridge.BridgeSettings;
|
||||
import com.bwssystems.HABridge.Configuration;
|
||||
import com.bwssystems.HABridge.BridgeSettingsDescriptor;
|
||||
import com.bwssystems.HABridge.JsonTransformer;
|
||||
import com.bwssystems.HABridge.api.UserCreateRequest;
|
||||
import com.bwssystems.HABridge.api.hue.DeviceResponse;
|
||||
@@ -46,7 +45,6 @@ import java.math.BigDecimal;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.InetAddress;
|
||||
import java.net.MulticastSocket;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -71,11 +69,11 @@ public class HueMulator {
|
||||
private Nest theNest;
|
||||
private HttpClient httpClient;
|
||||
private ObjectMapper mapper;
|
||||
private BridgeSettings bridgeSettings;
|
||||
private BridgeSettingsDescriptor bridgeSettings;
|
||||
private byte[] sendData;
|
||||
|
||||
|
||||
public HueMulator(BridgeSettings theBridgeSettings, DeviceRepository aDeviceRepository, HarmonyHome theHarmonyHome, NestHome aNestHome){
|
||||
public HueMulator(BridgeSettingsDescriptor theBridgeSettings, DeviceRepository aDeviceRepository, HarmonyHome theHarmonyHome, NestHome aNestHome){
|
||||
httpClient = HttpClients.createDefault();
|
||||
mapper = new ObjectMapper(); //armzilla: work around Echo incorrect content type and breaking mapping. Map manually
|
||||
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
@@ -441,38 +439,6 @@ public class HueMulator {
|
||||
|
||||
return responseString;
|
||||
});
|
||||
|
||||
// http://ip_address:port/api/control/restart CORS request
|
||||
options(HUE_CONTEXT + "/control/restart", "application/json", (request, response) -> {
|
||||
response.status(HttpStatus.SC_OK);
|
||||
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
|
||||
response.header("Access-Control-Allow-Methods", "GET, POST, PUT");
|
||||
response.header("Access-Control-Allow-Headers", request.headers("Access-Control-Request-Headers"));
|
||||
response.header("Content-Type", "text/html; charset=utf-8");
|
||||
return "";
|
||||
});
|
||||
// http://ip_address:port/api//control/restart sets the parameter restart the server
|
||||
put(HUE_CONTEXT + "/control/restart", "application/json", (request, response) -> {
|
||||
bridgeSettings.setRestart(true);
|
||||
pingListener();
|
||||
return "{\"control\":\"restarting\"}";
|
||||
});
|
||||
|
||||
// http://ip_address:port/api/control/stop CORS request
|
||||
options(HUE_CONTEXT + "/control/stop", "application/json", (request, response) -> {
|
||||
response.status(HttpStatus.SC_OK);
|
||||
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
|
||||
response.header("Access-Control-Allow-Methods", "GET, POST, PUT");
|
||||
response.header("Access-Control-Allow-Headers", request.headers("Access-Control-Request-Headers"));
|
||||
response.header("Content-Type", "text/html; charset=utf-8");
|
||||
return "";
|
||||
});
|
||||
// http://ip_address:port/api//control/stop sets the parameter stop the server
|
||||
put(HUE_CONTEXT + "/control/stop", "application/json", (request, response) -> {
|
||||
bridgeSettings.setStop(true);
|
||||
pingListener();
|
||||
return "{\"control\":\"stopping\"}";
|
||||
});
|
||||
}
|
||||
|
||||
/* light weight templating here, was going to use free marker but it was a bit too
|
||||
@@ -544,23 +510,4 @@ public class HueMulator {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void pingListener() {
|
||||
try {
|
||||
byte[] buf = new byte[256];
|
||||
String testData = "M-SEARCH * HTTP/1.1\nHOST: " + Configuration.UPNP_MULTICAST_ADDRESS + ":" + Configuration.UPNP_DISCOVERY_PORT + "ST: urn:schemas-upnp-org:device:CloudProxy:1\nMAN: \"ssdp:discover\"\nMX: 3";
|
||||
buf = testData.getBytes();
|
||||
MulticastSocket socket = new MulticastSocket(Configuration.UPNP_DISCOVERY_PORT);
|
||||
|
||||
InetAddress group = InetAddress.getByName(Configuration.UPNP_MULTICAST_ADDRESS);
|
||||
DatagramPacket packet;
|
||||
packet = new DatagramPacket(buf, buf.length, group, Configuration.UPNP_DISCOVERY_PORT);
|
||||
socket.send(packet);
|
||||
|
||||
socket.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
log.warn("Error pinging listener.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,21 +80,27 @@ public class UpnpListener {
|
||||
if(isSSDPDiscovery(packet)){
|
||||
sendUpnpResponse(responseSocket, packet.getAddress(), packet.getPort());
|
||||
}
|
||||
if(bridgeSettings.isRestart() || bridgeSettings.isStop())
|
||||
if(bridgeSettings.isReinit() || bridgeSettings.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(bridgeSettings.isRestart())
|
||||
if(bridgeSettings.isReinit())
|
||||
log.info("UPNP Discovery Listener - ended, restart found");
|
||||
if(bridgeSettings.isStop())
|
||||
log.info("UPNP Discovery Listener - ended, stop found");
|
||||
if(!bridgeSettings.isStop()&& !bridgeSettings.isRestart())
|
||||
if(!bridgeSettings.isStop()&& !bridgeSettings.isReinit())
|
||||
log.info("UPNP Discovery Listener - ended, error found");
|
||||
return bridgeSettings.isRestart();
|
||||
return bridgeSettings.isReinit();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,8 +3,7 @@ package com.bwssystems.HABridge.upnp;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.bwssystems.HABridge.BridgeSettings;
|
||||
import com.bwssystems.HABridge.JsonTransformer;
|
||||
import com.bwssystems.HABridge.BridgeSettingsDescriptor;
|
||||
|
||||
import static spark.Spark.get;
|
||||
|
||||
@@ -12,11 +11,9 @@ import static spark.Spark.get;
|
||||
*
|
||||
*/
|
||||
public class UpnpSettingsResource {
|
||||
private static final String UPNP_CONTEXT = "/upnp";
|
||||
|
||||
private Logger log = LoggerFactory.getLogger(UpnpSettingsResource.class);
|
||||
|
||||
private BridgeSettings 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"
|
||||
+ "<specVersion>\n" + "<major>1</major>\n" + "<minor>0</minor>\n" + "</specVersion>\n"
|
||||
@@ -40,22 +37,9 @@ public class UpnpSettingsResource {
|
||||
+ "<depth>24</depth>\n" + "<url>hue_logo_3.png</url>\n" + "</icon>\n" + "</iconList>\n" + "</device>\n"
|
||||
+ "</root>\n";
|
||||
|
||||
public UpnpSettingsResource(BridgeSettings theBridgeSettings) {
|
||||
public UpnpSettingsResource(BridgeSettingsDescriptor theBridgeSettings) {
|
||||
super();
|
||||
this.theSettings = new BridgeSettings();
|
||||
this.theSettings.setDevMode(theBridgeSettings.isDevMode());
|
||||
this.theSettings.setHarmonyAddress(theBridgeSettings.getHarmonyAddress());
|
||||
this.theSettings.setServerPort(theBridgeSettings.getServerPort());
|
||||
this.theSettings.setTraceupnp(theBridgeSettings.isTraceupnp());
|
||||
this.theSettings.setUpnpConfigAddress(theBridgeSettings.getUpnpConfigAddress());
|
||||
this.theSettings.setUpnpDeviceDb(theBridgeSettings.getUpnpDeviceDb());
|
||||
this.theSettings.setButtonsleep(theBridgeSettings.getButtonsleep());
|
||||
this.theSettings.setUpnpResponsePort(theBridgeSettings.getUpnpResponsePort());
|
||||
this.theSettings.setUpnpStrict(theBridgeSettings.isUpnpStrict());
|
||||
this.theSettings.setVeraAddress(theBridgeSettings.getVeraAddress());
|
||||
this.theSettings.setVeraconfigured(theBridgeSettings.isValidVera());
|
||||
this.theSettings.setHarmonyconfigured(theBridgeSettings.isValidHarmony());
|
||||
this.theSettings.setNestConfigured(theBridgeSettings.isValidNest());
|
||||
this.theSettings = theBridgeSettings;
|
||||
}
|
||||
|
||||
public void setupServer() {
|
||||
@@ -88,14 +72,5 @@ public class UpnpSettingsResource {
|
||||
|
||||
return filledTemplate;
|
||||
} );
|
||||
|
||||
// http://ip_address:port/upnp/settings which returns the bridge configuration settings
|
||||
get(UPNP_CONTEXT + "/settings", "application/json", (request, response) -> {
|
||||
log.debug("bridge settings requested from " + request.ip());
|
||||
|
||||
response.status(200);
|
||||
|
||||
return theSettings;
|
||||
}, new JsonTransformer());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import java.util.Set;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.bwssystems.HABridge.BridgeSettings;
|
||||
import com.bwssystems.HABridge.BridgeSettingsDescriptor;
|
||||
import com.bwssystems.nest.controller.Home;
|
||||
import com.bwssystems.nest.controller.Nest;
|
||||
import com.bwssystems.nest.controller.NestSession;
|
||||
@@ -23,7 +23,7 @@ public class NestHome {
|
||||
private Nest theNest;
|
||||
private ArrayList<NestItem> nestItems;
|
||||
|
||||
public NestHome(BridgeSettings bridgeSettings) {
|
||||
public NestHome(BridgeSettingsDescriptor bridgeSettings) {
|
||||
theSession = null;
|
||||
theNest = null;
|
||||
nestItems = null;
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.bwssystems.HABridge.BridgeSettings;
|
||||
import com.bwssystems.HABridge.BridgeSettingsDescriptor;
|
||||
import com.bwssystems.HABridge.IpList;
|
||||
import com.bwssystems.HABridge.NamedIP;
|
||||
|
||||
@@ -21,7 +22,7 @@ public class HarmonyHome {
|
||||
private static final Logger log = LoggerFactory.getLogger(HarmonyHome.class);
|
||||
private Map<String, HarmonyServer> hubs;
|
||||
|
||||
public HarmonyHome(BridgeSettings bridgeSettings) {
|
||||
public HarmonyHome(BridgeSettingsDescriptor bridgeSettings) {
|
||||
super();
|
||||
hubs = new HashMap<String, HarmonyServer>();
|
||||
if(!bridgeSettings.isValidHarmony() && !bridgeSettings.isDevMode())
|
||||
|
||||
@@ -7,7 +7,7 @@ import javax.inject.Inject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.bwssystems.HABridge.BridgeSettings;
|
||||
import com.bwssystems.HABridge.BridgeSettingsDescriptor;
|
||||
import com.bwssystems.HABridge.NamedIP;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
@@ -36,7 +36,7 @@ public class HarmonyServer {
|
||||
myNameAndIP = theHarmonyAddress;
|
||||
}
|
||||
|
||||
public static HarmonyServer setup(BridgeSettings bridgeSettings, NamedIP theHarmonyAddress) throws Exception {
|
||||
public static HarmonyServer setup(BridgeSettingsDescriptor bridgeSettings, NamedIP theHarmonyAddress) throws Exception {
|
||||
if(!bridgeSettings.isValidHarmony() && !bridgeSettings.isDevMode()) {
|
||||
return new HarmonyServer(theHarmonyAddress);
|
||||
}
|
||||
@@ -50,7 +50,7 @@ public class HarmonyServer {
|
||||
return mainObject;
|
||||
}
|
||||
|
||||
private void execute(BridgeSettings mySettings) throws Exception {
|
||||
private void execute(BridgeSettingsDescriptor mySettings) throws Exception {
|
||||
Boolean noopCalls = Boolean.parseBoolean(System.getProperty("noop.calls", "false"));
|
||||
String modeString = "";
|
||||
if(dummyProvider != null)
|
||||
|
||||
@@ -9,7 +9,7 @@ import java.util.Map;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.bwssystems.HABridge.BridgeSettings;
|
||||
import com.bwssystems.HABridge.BridgeSettingsDescriptor;
|
||||
import com.bwssystems.HABridge.NamedIP;
|
||||
import com.bwssystems.luupRequests.Device;
|
||||
import com.bwssystems.luupRequests.Scene;
|
||||
@@ -18,7 +18,7 @@ public class VeraHome {
|
||||
private static final Logger log = LoggerFactory.getLogger(VeraHome.class);
|
||||
private Map<String, VeraInfo> veras;
|
||||
|
||||
public VeraHome(BridgeSettings bridgeSettings) {
|
||||
public VeraHome(BridgeSettingsDescriptor bridgeSettings) {
|
||||
veras = new HashMap<String, VeraInfo>();
|
||||
if(!bridgeSettings.isValidVera())
|
||||
return;
|
||||
|
||||
@@ -4,6 +4,9 @@ app.config(function ($routeProvider) {
|
||||
$routeProvider.when('/#', {
|
||||
templateUrl: 'views/configuration.html',
|
||||
controller: 'ViewingController'
|
||||
}).when('/system', {
|
||||
templateUrl: 'views/system.html',
|
||||
controller: 'SystemController'
|
||||
}).when('/editor', {
|
||||
templateUrl: 'views/editor.html',
|
||||
controller: 'AddingController'
|
||||
@@ -38,7 +41,7 @@ app.run( function (bridgeService) {
|
||||
|
||||
app.service('bridgeService', function ($http, $window, ngToast) {
|
||||
var self = this;
|
||||
this.state = {base: window.location.origin + "/api/devices", upnpbase: window.location.origin + "/upnp/settings", huebase: window.location.origin + "/api", backups: [], devices: [], device: [], settings: [], olddevicename: "", error: "", showVera: false, showHarmony: false, showNest: false, habridgeversion: ""};
|
||||
this.state = {base: window.location.origin + "/api/devices", systemsbase: window.location.origin + "/system", huebase: window.location.origin + "/api", configs: [], backups: [], devices: [], device: [], settings: [], olddevicename: "", error: "", showVera: false, showHarmony: false, showNest: false, habridgeversion: ""};
|
||||
|
||||
this.viewDevices = function () {
|
||||
this.state.error = "";
|
||||
@@ -59,7 +62,7 @@ app.service('bridgeService', function ($http, $window, ngToast) {
|
||||
|
||||
this.getHABridgeVersion = function () {
|
||||
this.state.error = "";
|
||||
return $http.get(this.state.base + "/habridge/version").then(
|
||||
return $http.get(this.state.systemsbase + "/habridge/version").then(
|
||||
function (response) {
|
||||
self.state.habridgeversion = response.data.version;
|
||||
},
|
||||
@@ -96,7 +99,7 @@ app.service('bridgeService', function ($http, $window, ngToast) {
|
||||
|
||||
this.loadBridgeSettings = function () {
|
||||
this.state.error = "";
|
||||
return $http.get(this.state.upnpbase).then(
|
||||
return $http.get(this.state.systemsbase + "/settings").then(
|
||||
function (response) {
|
||||
self.state.settings = response.data;
|
||||
self.updateShowVera();
|
||||
@@ -130,6 +133,22 @@ app.service('bridgeService', function ($http, $window, ngToast) {
|
||||
);
|
||||
};
|
||||
|
||||
this.viewConfigs = function () {
|
||||
this.state.error = "";
|
||||
return $http.get(this.state.systemsbase + "/backup/available").then(
|
||||
function (response) {
|
||||
self.state.configs = response.data;
|
||||
},
|
||||
function (error) {
|
||||
if (error.data) {
|
||||
$window.alert("Get Configs Error: " + error.data.message);
|
||||
} else {
|
||||
$window.alert("Get Configs Error: unknown");
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
this.viewNestItems = function () {
|
||||
this.state.error = "";
|
||||
if(!this.state.showNest)
|
||||
@@ -344,7 +363,59 @@ app.service('bridgeService', function ($http, $window, ngToast) {
|
||||
if (error.data) {
|
||||
self.state.error = error.data.message;
|
||||
}
|
||||
self.state.error = "Backup Db File Error: unknown";
|
||||
self.state.error = "Delete Backup Db File Error: unknown";
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
this.backupSettings = function (afilename) {
|
||||
this.state.error = "";
|
||||
return $http.put(this.state.systemsbase + "/backup/create", {
|
||||
filename: afilename
|
||||
}).then(
|
||||
function (response) {
|
||||
self.viewConfigs();
|
||||
},
|
||||
function (error) {
|
||||
if (error.data) {
|
||||
self.state.error = error.data.message;
|
||||
}
|
||||
self.state.error = "Backup Settings Error: unknown";
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
this.restoreSettings = function (afilename) {
|
||||
this.state.error = "";
|
||||
return $http.post(this.state.systemsbase + "/backup/restore", {
|
||||
filename: afilename
|
||||
}).then(
|
||||
function (response) {
|
||||
self.viewConfigs();
|
||||
self.viewDevices();
|
||||
},
|
||||
function (error) {
|
||||
if (error.data) {
|
||||
self.state.error = error.data.message;
|
||||
}
|
||||
self.state.error = "Backup Settings Restore Error: unknown";
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
this.deleteSettingsBackup = function (afilename) {
|
||||
this.state.error = "";
|
||||
return $http.post(this.state.systemsbase + "/backup/delete", {
|
||||
filename: afilename
|
||||
}).then(
|
||||
function (response) {
|
||||
self.viewConfigs();
|
||||
},
|
||||
function (error) {
|
||||
if (error.data) {
|
||||
self.state.error = error.data.message;
|
||||
}
|
||||
self.state.error = "Delete Backup Settings File Error: unknown";
|
||||
}
|
||||
);
|
||||
};
|
||||
@@ -410,6 +481,46 @@ app.service('bridgeService', function ($http, $window, ngToast) {
|
||||
};
|
||||
});
|
||||
|
||||
app.controller('SystemController', function ($scope, $location, $http, $window, bridgeService) {
|
||||
bridgeService.viewConfigs();
|
||||
$scope.bridge = bridgeService.state;
|
||||
$scope.optionalbackupname = "";
|
||||
$scope.visible = false;
|
||||
$scope.imgUrl = "glyphicon glyphicon-plus";
|
||||
$scope.visibleBk = false;
|
||||
$scope.imgBkUrl = "glyphicon glyphicon-plus";
|
||||
$scope.setBridgeUrl = function (url) {
|
||||
bridgeService.state.base = url;
|
||||
bridgeService.viewDevices();
|
||||
};
|
||||
$scope.goBridgeUrl = function (url) {
|
||||
window.open(url, "_blank");
|
||||
};
|
||||
$scope.backupSettings = function (optionalbackupname) {
|
||||
bridgeService.backupSettings(optionalbackupname);
|
||||
};
|
||||
$scope.restoreSettings = function (backupname) {
|
||||
bridgeService.restoreSettings(backupname);
|
||||
};
|
||||
$scope.deleteSettingsBackup = function (backupname) {
|
||||
bridgeService.deleteSettingsBackup(backupname);
|
||||
};
|
||||
$scope.toggle = function () {
|
||||
$scope.visible = !$scope.visible;
|
||||
if($scope.visible)
|
||||
$scope.imgUrl = "glyphicon glyphicon-minus";
|
||||
else
|
||||
$scope.imgUrl = "glyphicon glyphicon-plus";
|
||||
};
|
||||
$scope.toggleBk = function () {
|
||||
$scope.visibleBk = !$scope.visibleBk;
|
||||
if($scope.visibleBk)
|
||||
$scope.imgBkUrl = "glyphicon glyphicon-minus";
|
||||
else
|
||||
$scope.imgBkUrl = "glyphicon glyphicon-plus";
|
||||
};
|
||||
});
|
||||
|
||||
app.controller('ViewingController', function ($scope, $location, $http, $window, bridgeService) {
|
||||
|
||||
bridgeService.viewDevices();
|
||||
@@ -432,13 +543,6 @@ app.controller('ViewingController', function ($scope, $location, $http, $window,
|
||||
$scope.testUrl = function (device, type) {
|
||||
bridgeService.testUrl(device, type);
|
||||
};
|
||||
$scope.setBridgeUrl = function (url) {
|
||||
bridgeService.state.base = url;
|
||||
bridgeService.viewDevices();
|
||||
};
|
||||
$scope.goBridgeUrl = function (url) {
|
||||
window.open(url, "_blank");
|
||||
};
|
||||
$scope.editDevice = function (device) {
|
||||
bridgeService.editDevice(device);
|
||||
$location.path('/editdevice');
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<ul class="nav nav-pills" role="tablist">
|
||||
<li role="presentation" class="active"><a href="#">Configuration</a></li>
|
||||
<li role="presentation" class="active"><a href="#">Bridge Devices</a></li>
|
||||
<li role="presentation"><a href="#/system">Bridge Control</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>
|
||||
@@ -64,82 +65,6 @@
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="panel panel-default bridgeServer">
|
||||
<div class="panel-heading">
|
||||
<h1 class="panel-title">Bridge Settings <a ng-click="toggle()"><span class={{imgUrl}} aria-hidden="true"></a></h1>
|
||||
</div>
|
||||
<div ng-if="visible" 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="bridge-base">Bridge
|
||||
server</label>
|
||||
|
||||
<div class="col-xs-8 col-sm-7">
|
||||
<input id="bridge-base" class="form-control" type="text"
|
||||
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>
|
||||
</form>
|
||||
<table class="table table-bordered table-striped table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Setting</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr>
|
||||
<td>upnp.config.address</td>
|
||||
<td>{{bridge.settings.upnpconfigaddress}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>server.port</td>
|
||||
<td>{{bridge.settings.serverport}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>upnp.devices.db</td>
|
||||
<td>{{bridge.settings.upnpdevicedb}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>upnp.response.port</td>
|
||||
<td>{{bridge.settings.upnpresponseport}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>vera.address</td>
|
||||
<td>{{bridge.settings.veraaddress}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>harmony.address</td>
|
||||
<td>{{bridge.settings.harmonyaddress}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>upnp.strict</td>
|
||||
<td>{{bridge.settings.upnpstrict}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>trace.upnp</td>
|
||||
<td>{{bridge.settings.traceupnp}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>dev.mode</td>
|
||||
<td>{{bridge.settings.devmode}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>nest.configured</td>
|
||||
<td>{{bridge.settings.nestconfigured}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>button.sleep</td>
|
||||
<td>{{bridge.settings.buttonsleep}} ms</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-default backup">
|
||||
<div class="panel-heading">
|
||||
<h1 class="panel-title">Bridge Device DB Backup <a ng-click="toggleBk()"><span class={{imgBkUrl}} aria-hidden="true"></a></h1>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<ul class="nav nav-pills" role="tablist">
|
||||
<li role="presentation"><a href="#">Configuration</a></li>
|
||||
<li role="presentation"><a href="#">Bridge Devices</a></li>
|
||||
<li role="presentation"><a href="#/system">Bridge Control</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>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<ul class="nav nav-pills" role="tablist">
|
||||
<li role="presentation"><a href="#">Configuration</a></li>
|
||||
<li role="presentation"><a href="#">Bridge Devices</a></li>
|
||||
<li role="presentation"><a href="#/system">Bridge Control</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>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<ul class="nav nav-pills" role="tablist">
|
||||
<li role="presentation"><a href="#">Configuration</a></li>
|
||||
<li role="presentation"><a href="#">Bridge Devices</a></li>
|
||||
<li role="presentation"><a href="#/system">Bridge Control</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 role="presentation" class="active"><a href="#/harmonyactivities">Harmony Activities</a></li>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<ul class="nav nav-pills" role="tablist">
|
||||
<li role="presentation"><a href="#">Configuration</a></li>
|
||||
<li role="presentation"><a href="#">Bridge Devices</a></li>
|
||||
<li role="presentation"><a href="#/system">Bridge Control</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 role="presentation"><a href="#/harmonyactivities">Harmony Activities</a></li>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<ul class="nav nav-pills" role="tablist">
|
||||
<li role="presentation"><a href="#">Configuration</a></li>
|
||||
<li role="presentation"><a href="#">Bridge Devices</a></li>
|
||||
<li role="presentation"><a href="#/system">Bridge Control</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>
|
||||
|
||||
137
src/main/resources/public/views/system.html
Normal file
137
src/main/resources/public/views/system.html
Normal file
@@ -0,0 +1,137 @@
|
||||
<ul class="nav nav-pills" role="tablist">
|
||||
<li role="presentation"><a href="#">Bridge Devices</a></li>
|
||||
<li role="presentation" class="active"><a href="#/system">Bridge Control</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 ng-controller="ErrorsController">
|
||||
<div ng-if="bridge.error"
|
||||
class="alert alert-warning alert-dismissible" role="alert">
|
||||
<button type="button" class="close" data-dismiss="alert"
|
||||
aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
|
||||
<h2 ng-show='bridge.error != ""'>ERROR</h2>
|
||||
|
||||
<div ng-show='bridge.error != ""'>{{bridge.error}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-default bridgeServer">
|
||||
<div class="panel-heading">
|
||||
<h1 class="panel-title">Bridge Settings</h1>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
|
||||
<form class="form-horizontal">
|
||||
<div class="form-group">
|
||||
<label class="col-xs-12 col-sm-2 control-label" for="bridge-base">Bridge
|
||||
server</label>
|
||||
|
||||
<div class="col-xs-8 col-sm-7">
|
||||
<input id="bridge-base" class="form-control" type="text"
|
||||
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>
|
||||
</form>
|
||||
<table class="table table-bordered table-striped table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Setting</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr>
|
||||
<td>upnp.config.address</td>
|
||||
<td>{{bridge.settings.upnpconfigaddress}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>server.port</td>
|
||||
<td>{{bridge.settings.serverport}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>upnp.devices.db</td>
|
||||
<td>{{bridge.settings.upnpdevicedb}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>upnp.response.port</td>
|
||||
<td>{{bridge.settings.upnpresponseport}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>vera.address</td>
|
||||
<td>{{bridge.settings.veraaddress}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>harmony.address</td>
|
||||
<td>{{bridge.settings.harmonyaddress}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>upnp.strict</td>
|
||||
<td>{{bridge.settings.upnpstrict}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>trace.upnp</td>
|
||||
<td>{{bridge.settings.traceupnp}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>dev.mode</td>
|
||||
<td>{{bridge.settings.devmode}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>nest.configured</td>
|
||||
<td>{{bridge.settings.nestconfigured}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>button.sleep</td>
|
||||
<td>{{bridge.settings.buttonsleep}} ms</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-default backup">
|
||||
<div class="panel-heading">
|
||||
<h1 class="panel-title">Bridge Settings 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 Settings 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="backupSettings(optionalbackupname)">Backup Settings</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.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>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<ul class="nav nav-pills" role="tablist">
|
||||
<li role="presentation"><a href="#">Configuration</a></li>
|
||||
<li role="presentation"><a href="#">Bridge Devices</a></li>
|
||||
<li role="presentation"><a href="#/system">Bridge Control</a></li>
|
||||
<li role="presentation" class="active"><a href="#/veradevices">Vera Devices</a></li>
|
||||
<li role="presentation"><a href="#/verascenes">Vera Scenes</a></li>
|
||||
<li ng-if="bridge.showHarmony" role="presentation"><a href="#/harmonyactivities">Harmony Activities</a></li>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<ul class="nav nav-pills" role="tablist">
|
||||
<li role="presentation"><a href="#">Configuration</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="#/veradevices">Vera Devices</a></li>
|
||||
<li role="presentation" class="active"><a href="#/verascenes">Vera Scenes</a></li>
|
||||
<li ng-if="bridge.showHarmony" role="presentation"><a href="#/harmonyactivities">Harmony Activities</a></li>
|
||||
|
||||
Reference in New Issue
Block a user