mirror of
https://github.com/bwssytems/ha-bridge.git
synced 2025-12-18 08:13:23 +00:00
Compare commits
99 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
69b510ae18 | ||
|
|
e86b700e93 | ||
|
|
a05b933e43 | ||
|
|
fe0b072b4e | ||
|
|
3e76e6298a | ||
|
|
f266945b7e | ||
|
|
2d3fac691b | ||
|
|
5f6bfae41a | ||
|
|
79d5b5da28 | ||
|
|
45e2b63f98 | ||
|
|
b6b9089ec4 | ||
|
|
063055f5c8 | ||
|
|
c1dc89704d | ||
|
|
f97c718568 | ||
|
|
d05b6bea5c | ||
|
|
2f567cd604 | ||
|
|
3971c81449 | ||
|
|
e1b5aede66 | ||
|
|
14c3614856 | ||
|
|
1311d4a68d | ||
|
|
9cbc290768 | ||
|
|
f90f39e5f1 | ||
|
|
07fa11b9ff | ||
|
|
df04d542db | ||
|
|
92ab02145e | ||
|
|
d9916b7662 | ||
|
|
f8349f12bc | ||
|
|
12823704f3 | ||
|
|
7490cf72a3 | ||
|
|
ce220d999a | ||
|
|
9a438abf79 | ||
|
|
ce97e928ad | ||
|
|
56481f3f72 | ||
|
|
55ed9ba4c2 | ||
|
|
df67980bd6 | ||
|
|
b6b78c4849 | ||
|
|
b1d1f2ac46 | ||
|
|
750056df06 | ||
|
|
3f13e957ad | ||
|
|
afc254720c | ||
|
|
943e4420e6 | ||
|
|
c9e6cd079f | ||
|
|
faae6aa31f | ||
|
|
c25f08f142 | ||
|
|
d6ad9d288e | ||
|
|
3400c4d43a | ||
|
|
ddcbea001c | ||
|
|
9a35e47c27 | ||
|
|
199fcce549 | ||
|
|
bfeb382d1f | ||
|
|
3a93d9e98f | ||
|
|
3b22e3f711 | ||
|
|
5c1f1f5b96 | ||
|
|
82788f1ecd | ||
|
|
d5920e1454 | ||
|
|
b26a63bb7a | ||
|
|
f17cea3c9d | ||
|
|
7f68285a43 | ||
|
|
cb46a13802 | ||
|
|
de07393e6e | ||
|
|
4b40b03da4 | ||
|
|
4f5d4acf56 | ||
|
|
271bd3913c | ||
|
|
869ffaaf36 | ||
|
|
5a73cc20a9 | ||
|
|
1a936c631c | ||
|
|
1a8a6f7a6f | ||
|
|
879d3b5326 | ||
|
|
3313548ec2 | ||
|
|
e6db6e11e5 | ||
|
|
dc28eb2984 | ||
|
|
b8acb4a52c | ||
|
|
c843e8d1ac | ||
|
|
21fdaf4545 | ||
|
|
db192df2c6 | ||
|
|
4a24d263c1 | ||
|
|
3394559539 | ||
|
|
47074ff60f | ||
|
|
047a7de612 | ||
|
|
7fc7f00308 | ||
|
|
14e940134c | ||
|
|
1897633e75 | ||
|
|
5a052d9374 | ||
|
|
4b048c2a7f | ||
|
|
27f77b9caa | ||
|
|
18c47ee5e4 | ||
|
|
27dd8475e9 | ||
|
|
37b381085c | ||
|
|
b2a30f5771 | ||
|
|
b88b3fa245 | ||
|
|
52aac32474 | ||
|
|
037b151729 | ||
|
|
3f3d643053 | ||
|
|
f27d905869 | ||
|
|
4c694cb285 | ||
|
|
ca2c5f7b04 | ||
|
|
0c49df1473 | ||
|
|
fe613f7688 | ||
|
|
4b247557d4 |
9
.gitignore
vendored
9
.gitignore
vendored
@@ -14,3 +14,12 @@ data
|
||||
/.classpath
|
||||
|
||||
sftp-config\.json
|
||||
/bin/
|
||||
.vscode/launch.json
|
||||
.vscode/launch.test.json
|
||||
.vscode/settings.json
|
||||
.vscode/tasks.json
|
||||
# dependencies
|
||||
/node_modules
|
||||
|
||||
package-lock.json
|
||||
253
pom.xml
253
pom.xml
@@ -1,160 +1,198 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.bwssystems.HABridge</groupId>
|
||||
<artifactId>ha-bridge</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.next_e</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>HA Bridge</name>
|
||||
<description>Emulates a Philips Hue bridge to allow the Amazon Echo to hook up to other HA systems, i.e. Vera or Harmony Hub or Nest, using lightweight frameworks</description>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>jitpack.io</id>
|
||||
<url>https://jitpack.io</url>
|
||||
<id>jitpack.io</id>
|
||||
<url>https://jitpack.io</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>Eclipse Paho Repo</id>
|
||||
<url>https://repo.eclipse.org/content/repositories/paho-releases/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>Eclipse Paho Repo</id>
|
||||
<url>https://repo.eclipse.org/content/repositories/paho-releases/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.github.bwssytems</groupId>
|
||||
<artifactId>harmony-java-client</artifactId>
|
||||
<version>1.1.5</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>log4j-over-slf4j</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<groupId>com.github.bwssytems</groupId>
|
||||
<artifactId>harmony-java-client</artifactId>
|
||||
<version>master-SNAPSHOT</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>log4j-over-slf4j</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.bwssytems</groupId>
|
||||
<artifactId>nest-controller</artifactId>
|
||||
<version>1.0.14</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>log4j-over-slf4j</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sparkjava</groupId>
|
||||
<artifactId>spark-core</artifactId>
|
||||
<version>2.7.1</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<groupId>org.slf4j</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<groupId>com.github.bwssytems</groupId>
|
||||
<artifactId>nest-controller</artifactId>
|
||||
<version>1.0.14</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>log4j-over-slf4j</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sparkjava</groupId>
|
||||
<artifactId>spark-core</artifactId>
|
||||
<version>2.7.2</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<groupId>org.slf4j</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>4.5.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpcore</artifactId>
|
||||
<version>4.4.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.7.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpcore</artifactId>
|
||||
<version>4.4.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.7.24</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>1.1.5</version>
|
||||
<version>1.2.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.6.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.java.dev.eval</groupId>
|
||||
<artifactId>eval</artifactId>
|
||||
<version>0.5</version>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.6.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.java.dev.eval</groupId>
|
||||
<artifactId>eval</artifactId>
|
||||
<version>0.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.inject</groupId>
|
||||
<artifactId>guice</artifactId>
|
||||
<version>4.0-beta4</version>
|
||||
<version>4.1.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.igniterealtime.smack</groupId>
|
||||
<artifactId>smack-core</artifactId>
|
||||
<version>4.0.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.paho</groupId>
|
||||
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
|
||||
<version>1.1.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.11</version>
|
||||
<groupId>org.igniterealtime.smack</groupId>
|
||||
<artifactId>smack-core</artifactId>
|
||||
<version>4.2.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.bwssytems</groupId>
|
||||
<artifactId>lifx-sdk-java</artifactId>
|
||||
<version>2.1.6</version>
|
||||
<groupId>org.eclipse.paho</groupId>
|
||||
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
|
||||
<version>1.2.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.5</version>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.bwssytems</groupId>
|
||||
<artifactId>lifx-sdk-java</artifactId>
|
||||
<version>2.1.6</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.mob41</groupId>
|
||||
<artifactId>broadlink-java-api</artifactId>
|
||||
<version>master-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.5</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<includes>
|
||||
<include>version.properties</include>
|
||||
</includes>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<excludes>
|
||||
<exclude>version.properties</exclude>
|
||||
</excludes>
|
||||
<filtering>false</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<includes>
|
||||
<include>version.properties</include>
|
||||
</includes>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<excludes>
|
||||
<exclude>version.properties</exclude>
|
||||
</excludes>
|
||||
<filtering>false</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-enforcer-plugin</artifactId>
|
||||
<version>3.0.0-M2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>enforce-maven</id>
|
||||
<goals>
|
||||
<goal>enforce</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<rules>
|
||||
<requireMavenVersion>
|
||||
<version>3.6</version>
|
||||
</requireMavenVersion>
|
||||
</rules>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin> <plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.1</version>
|
||||
<configuration>
|
||||
<release>11</release>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>3.0.0-M3</version>
|
||||
<configuration>
|
||||
<skipTests>true</skipTests>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>2.4.3</version>
|
||||
<version>3.2.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
@@ -216,8 +254,7 @@
|
||||
</filter>
|
||||
</filters>
|
||||
<transformers>
|
||||
<transformer
|
||||
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||
<mainClass>com.bwssystems.HABridge.HABridge</mainClass>
|
||||
</transformer>
|
||||
</transformers>
|
||||
|
||||
@@ -355,7 +355,7 @@ public class BridgeSecurity {
|
||||
|
||||
public void removeAuthenticatedUser(Request request) {
|
||||
request.session().removeAttribute(USER_SESSION_ID);
|
||||
|
||||
request.session().invalidate();
|
||||
}
|
||||
|
||||
public User getAuthenticatedUser(Request request) {
|
||||
|
||||
@@ -12,8 +12,8 @@ import java.nio.file.Paths;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.nio.file.attribute.PosixFilePermission;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
@@ -24,6 +24,7 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.bwssystems.HABridge.util.BackupHandler;
|
||||
import com.bwssystems.HABridge.util.JsonTransformer;
|
||||
import com.bwssystems.HABridge.util.ParseRoute;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
public class BridgeSettings extends BackupHandler {
|
||||
@@ -31,7 +32,7 @@ public class BridgeSettings extends BackupHandler {
|
||||
private BridgeSettingsDescriptor theBridgeSettings;
|
||||
private BridgeControlDescriptor bridgeControl;
|
||||
private BridgeSecurity bridgeSecurity;
|
||||
private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd'T'HHmmss");
|
||||
private static final DateTimeFormatter dateTimeFormat = DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss");
|
||||
|
||||
public BridgeSettings() {
|
||||
super();
|
||||
@@ -58,10 +59,10 @@ public class BridgeSettings extends BackupHandler {
|
||||
public BridgeSecurity getBridgeSecurity() {
|
||||
return bridgeSecurity;
|
||||
}
|
||||
public static String getCurrentDate() {
|
||||
return dateFormat.format(new Date());
|
||||
}
|
||||
|
||||
public String getCurrentDate() {
|
||||
return LocalDateTime.now().format(dateTimeFormat);
|
||||
}
|
||||
|
||||
public void buildSettings() {
|
||||
String addressString = null;
|
||||
String theVeraAddress = null;
|
||||
@@ -76,7 +77,6 @@ public class BridgeSettings extends BackupHandler {
|
||||
}
|
||||
String serverPortOverride = System.getProperty("server.port");
|
||||
String serverIpOverride = System.getProperty("server.ip");
|
||||
String upnpStrictOverride = System.getProperty("upnp.strict", "true");
|
||||
if(configFileProperty != null)
|
||||
{
|
||||
log.info("reading from config file: " + configFileProperty);
|
||||
@@ -159,15 +159,16 @@ public class BridgeSettings extends BackupHandler {
|
||||
}
|
||||
theBridgeSettings.setSomfyAddress(theSomfyList);
|
||||
|
||||
theBridgeSettings.setUpnpStrict(Boolean.parseBoolean(System.getProperty("upnp.strict", "true")));
|
||||
// theBridgeSettings.setUpnpStrict(Boolean.parseBoolean(System.getProperty("upnp.strict", "true")));
|
||||
theBridgeSettings.setTraceupnp(Boolean.parseBoolean(System.getProperty("trace.upnp", "false")));
|
||||
theBridgeSettings.setButtonsleep(Integer.parseInt(System.getProperty("button.sleep", Configuration.DEFAULT_BUTTON_SLEEP)));
|
||||
theBridgeSettings.setNestuser(System.getProperty("nest.user"));
|
||||
theBridgeSettings.setNestpwd(System.getProperty("nest.pwd"));
|
||||
}
|
||||
|
||||
ParseRoute aDefaultRoute = ParseRoute.getInstance();
|
||||
if(theBridgeSettings.getUpnpConfigAddress() == null || theBridgeSettings.getUpnpConfigAddress().trim().equals("") || theBridgeSettings.getUpnpConfigAddress().trim().equals("0.0.0.0")) {
|
||||
addressString = checkIpAddress(null, true);
|
||||
addressString = aDefaultRoute.getLocalIPAddress();
|
||||
if(addressString != null) {
|
||||
theBridgeSettings.setUpnpConfigAddress(addressString);
|
||||
log.info("Adding " + addressString + " as our default upnp config address.");
|
||||
@@ -177,8 +178,10 @@ public class BridgeSettings extends BackupHandler {
|
||||
}
|
||||
else {
|
||||
addressString = checkIpAddress(theBridgeSettings.getUpnpConfigAddress(), false);
|
||||
if(addressString == null)
|
||||
log.warn("The upnp config address, " + theBridgeSettings.getUpnpConfigAddress() + ", does not match any known IP's on this host.");
|
||||
if(addressString == null) {
|
||||
addressString = aDefaultRoute.getLocalIPAddress();
|
||||
log.warn("The upnp config address, " + theBridgeSettings.getUpnpConfigAddress() + ", does not match any known IP's on this host. Using default address: " + addressString);
|
||||
}
|
||||
}
|
||||
|
||||
if(theBridgeSettings.getUpnpResponsePort() == null)
|
||||
@@ -194,7 +197,7 @@ public class BridgeSettings extends BackupHandler {
|
||||
theBridgeSettings.setUpnpGroupDb(Configuration.GROUP_DB_DIRECTORY);
|
||||
|
||||
if(theBridgeSettings.getNumberoflogmessages() == null || theBridgeSettings.getNumberoflogmessages() <= 0)
|
||||
theBridgeSettings.setNumberoflogmessages(new Integer(Configuration.NUMBER_OF_LOG_MESSAGES));
|
||||
theBridgeSettings.setNumberoflogmessages(Integer.valueOf(Configuration.NUMBER_OF_LOG_MESSAGES));
|
||||
|
||||
if(theBridgeSettings.getButtonsleep() == null || theBridgeSettings.getButtonsleep() < 0)
|
||||
theBridgeSettings.setButtonsleep(Integer.parseInt(Configuration.DEFAULT_BUTTON_SLEEP));
|
||||
@@ -210,13 +213,18 @@ public class BridgeSettings extends BackupHandler {
|
||||
theBridgeSettings.setDomoticzconfigured(theBridgeSettings.isValidDomoticz());
|
||||
theBridgeSettings.setSomfyconfigured(theBridgeSettings.isValidSomfy());
|
||||
theBridgeSettings.setHomeWizardConfigured(theBridgeSettings.isValidHomeWizard());
|
||||
theBridgeSettings.setOpenhabconfigured(theBridgeSettings.isValidOpenhab());
|
||||
theBridgeSettings.setFhemconfigured(theBridgeSettings.isValidFhem());
|
||||
theBridgeSettings.setMoziotconfigured(theBridgeSettings.isValidMozIot());
|
||||
theBridgeSettings.setHomegenieconfigured(theBridgeSettings.isValidHomeGenie());
|
||||
// Lifx is either configured or not, so it does not need an update.
|
||||
if(serverPortOverride != null)
|
||||
theBridgeSettings.setServerPort(serverPortOverride);
|
||||
if(serverIpOverride != null)
|
||||
if(serverIpOverride != null) {
|
||||
theBridgeSettings.setWebaddress(serverIpOverride);
|
||||
if(upnpStrictOverride != null)
|
||||
theBridgeSettings.setUpnpStrict(Boolean.parseBoolean(upnpStrictOverride));
|
||||
theBridgeSettings.setUpnpConfigAddress(serverIpOverride);
|
||||
}
|
||||
|
||||
setupParams(Paths.get(theBridgeSettings.getConfigfile()), ".cfgbk", "habridge.config-");
|
||||
|
||||
bridgeSecurity.setSecurityData(theBridgeSettings.getSecurityData());
|
||||
|
||||
@@ -4,7 +4,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
//import com.bwssystems.HABridge.api.NameValue;
|
||||
import com.bwssystems.HABridge.api.hue.HueConstants;
|
||||
import com.bwssystems.HABridge.api.hue.WhitelistEntry;
|
||||
|
||||
@@ -87,6 +87,12 @@ public class BridgeSettingsDescriptor {
|
||||
@SerializedName("somfyaddress")
|
||||
@Expose
|
||||
private IpList somfyaddress;
|
||||
@SerializedName("openhabaddress")
|
||||
@Expose
|
||||
private IpList openhabaddress;
|
||||
@SerializedName("moziotaddress")
|
||||
@Expose
|
||||
private IpList moziotaddress;
|
||||
@SerializedName("hubversion")
|
||||
@Expose
|
||||
private String hubversion;
|
||||
@@ -99,7 +105,34 @@ public class BridgeSettingsDescriptor {
|
||||
@SerializedName("homewizardaddress")
|
||||
@Expose
|
||||
private IpList homewizardaddress;
|
||||
|
||||
@SerializedName("upnpsenddelay")
|
||||
@Expose
|
||||
private Integer upnpsenddelay;
|
||||
@SerializedName("fhemaddress")
|
||||
@Expose
|
||||
private IpList fhemaddress;
|
||||
@SerializedName("homegenieaddress")
|
||||
@Expose
|
||||
private IpList homegenieaddress;
|
||||
@SerializedName("lifxconfigured")
|
||||
@Expose
|
||||
private boolean lifxconfigured;
|
||||
@SerializedName("broadlinkconfigured")
|
||||
@Expose
|
||||
private boolean broadlinkconfigured;
|
||||
@SerializedName("tracestate")
|
||||
@Expose
|
||||
private boolean tracestate;
|
||||
@SerializedName("upnporiginal")
|
||||
@Expose
|
||||
private boolean upnporiginal;
|
||||
@SerializedName("seedid")
|
||||
@Expose
|
||||
private Integer seedid;
|
||||
// @SerializedName("activeloggers")
|
||||
// @Expose
|
||||
// private List<NameValue> activeloggers;
|
||||
|
||||
private boolean settingsChanged;
|
||||
private boolean veraconfigured;
|
||||
private boolean fibaroconfigured;
|
||||
@@ -111,16 +144,19 @@ public class BridgeSettingsDescriptor {
|
||||
private boolean hassconfigured;
|
||||
private boolean domoticzconfigured;
|
||||
private boolean somfyconfigured;
|
||||
private boolean lifxconfigured;
|
||||
private boolean homewizardconfigured;
|
||||
|
||||
private boolean openhabconfigured;
|
||||
private boolean fhemconfigured;
|
||||
private boolean moziotconfigured;
|
||||
private boolean homegenieconfigured;
|
||||
|
||||
// Deprecated settings
|
||||
private String haltoken;
|
||||
private boolean upnpstrict;
|
||||
|
||||
// private boolean upnpstrict;
|
||||
|
||||
public BridgeSettingsDescriptor() {
|
||||
super();
|
||||
this.upnpstrict = true;
|
||||
// this.upnpstrict = true;
|
||||
this.useupnpiface = false;
|
||||
this.userooms = false;
|
||||
this.traceupnp = false;
|
||||
@@ -136,6 +172,9 @@ public class BridgeSettingsDescriptor {
|
||||
this.domoticzconfigured = false;
|
||||
this.homewizardconfigured = false;
|
||||
this.lifxconfigured = false;
|
||||
this.openhabconfigured = false;
|
||||
this.moziotconfigured = false;
|
||||
this.homegenieconfigured = false;
|
||||
this.farenheit = true;
|
||||
this.securityData = null;
|
||||
this.settingsChanged = false;
|
||||
@@ -143,388 +182,657 @@ public class BridgeSettingsDescriptor {
|
||||
this.webaddress = "0.0.0.0";
|
||||
this.hubversion = HueConstants.HUB_VERSION;
|
||||
this.hubmac = null;
|
||||
// this.activeloggers = null;
|
||||
this.upnpsenddelay = Configuration.UPNP_SEND_DELAY;
|
||||
this.broadlinkconfigured = false;
|
||||
this.tracestate = false;
|
||||
this.upnporiginal = false;
|
||||
this.seedid = 100;
|
||||
}
|
||||
|
||||
public String getUpnpConfigAddress() {
|
||||
return upnpconfigaddress;
|
||||
}
|
||||
|
||||
public void setUpnpConfigAddress(String upnpConfigAddress) {
|
||||
this.upnpconfigaddress = upnpConfigAddress;
|
||||
}
|
||||
|
||||
public boolean isUseupnpiface() {
|
||||
return useupnpiface;
|
||||
}
|
||||
|
||||
public void setUseupnpiface(boolean useupnpiface) {
|
||||
this.useupnpiface = useupnpiface;
|
||||
}
|
||||
|
||||
public boolean isUserooms() {
|
||||
return userooms;
|
||||
}
|
||||
|
||||
public void setUserooms(boolean userooms) {
|
||||
this.userooms = userooms;
|
||||
}
|
||||
public Integer getServerPort() {
|
||||
|
||||
public Integer getServerPort() {
|
||||
return serverport;
|
||||
}
|
||||
|
||||
public void setServerPort(Integer serverPort) {
|
||||
this.serverport = serverPort;
|
||||
}
|
||||
|
||||
public void setServerPort(String serverPort) {
|
||||
this.serverport = Integer.valueOf(serverPort);
|
||||
}
|
||||
|
||||
public Integer getUpnpResponsePort() {
|
||||
return upnpresponseport;
|
||||
}
|
||||
|
||||
public void setUpnpResponsePort(Integer upnpResponsePort) {
|
||||
this.upnpresponseport = upnpResponsePort;
|
||||
}
|
||||
|
||||
public void setUpnpResponsePort(String upnpResponsePort) {
|
||||
this.upnpresponseport = Integer.valueOf(upnpResponsePort);
|
||||
}
|
||||
|
||||
public String getUpnpDeviceDb() {
|
||||
return upnpdevicedb;
|
||||
}
|
||||
|
||||
public void setUpnpDeviceDb(String upnpDeviceDb) {
|
||||
this.upnpdevicedb = upnpDeviceDb;
|
||||
}
|
||||
|
||||
public String getUpnpGroupDb() {
|
||||
return upnpgroupdb;
|
||||
}
|
||||
|
||||
public void setUpnpGroupDb(String upnpGroupDb) {
|
||||
this.upnpgroupdb = upnpGroupDb;
|
||||
}
|
||||
|
||||
public IpList getVeraAddress() {
|
||||
return veraaddress;
|
||||
}
|
||||
|
||||
public IpList getFibaroAddress() {
|
||||
return fibaroaddress;
|
||||
}
|
||||
|
||||
public IpList getSomfyAddress() {
|
||||
return somfyaddress;
|
||||
}
|
||||
|
||||
public IpList getHomeWizardAddress() {
|
||||
return homewizardaddress;
|
||||
}
|
||||
}
|
||||
|
||||
public void setVeraAddress(IpList veraAddress) {
|
||||
this.veraaddress = veraAddress;
|
||||
}
|
||||
|
||||
public void setFibaroAddress(IpList fibaroAddress) {
|
||||
this.fibaroaddress = fibaroAddress;
|
||||
}
|
||||
|
||||
public void setSomfyAddress(IpList somfyAddress) {
|
||||
this.somfyaddress = somfyAddress;
|
||||
}
|
||||
|
||||
public void setHomeWizardAddress(IpList homewizardaddress) {
|
||||
this.homewizardaddress = homewizardaddress;
|
||||
}
|
||||
|
||||
public IpList getHarmonyAddress() {
|
||||
return harmonyaddress;
|
||||
}
|
||||
|
||||
public void setHarmonyAddress(IpList harmonyaddress) {
|
||||
this.harmonyaddress = harmonyaddress;
|
||||
}
|
||||
/*
|
||||
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 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 boolean isFibaroconfigured() {
|
||||
return fibaroconfigured;
|
||||
}
|
||||
|
||||
public boolean isSomfyconfigured() {
|
||||
return somfyconfigured;
|
||||
}
|
||||
|
||||
public boolean isHomeWizardConfigured() {
|
||||
return homewizardconfigured;
|
||||
}
|
||||
}
|
||||
|
||||
public void setVeraconfigured(boolean veraconfigured) {
|
||||
this.veraconfigured = veraconfigured;
|
||||
}
|
||||
|
||||
public void setFibaroconfigured(boolean fibaroconfigured) {
|
||||
this.fibaroconfigured = fibaroconfigured;
|
||||
}
|
||||
|
||||
public void setSomfyconfigured(boolean somfyconfigured) {
|
||||
this.somfyconfigured = somfyconfigured;
|
||||
}
|
||||
|
||||
public void setHomeWizardConfigured(boolean homewizardconfigured) {
|
||||
this.homewizardconfigured = homewizardconfigured;
|
||||
}
|
||||
|
||||
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 Integer getNumberoflogmessages() {
|
||||
return numberoflogmessages;
|
||||
}
|
||||
|
||||
public void setNumberoflogmessages(Integer numberoflogmessages) {
|
||||
this.numberoflogmessages = numberoflogmessages;
|
||||
}
|
||||
|
||||
public boolean isFarenheit() {
|
||||
return farenheit;
|
||||
}
|
||||
|
||||
public void setFarenheit(boolean 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;
|
||||
}
|
||||
|
||||
protected void removeWhitelist() {
|
||||
whitelist = null;
|
||||
}
|
||||
|
||||
public boolean isSettingsChanged() {
|
||||
return settingsChanged;
|
||||
}
|
||||
|
||||
public void setSettingsChanged(boolean settingsChanged) {
|
||||
this.settingsChanged = settingsChanged;
|
||||
}
|
||||
|
||||
public String getMyechourl() {
|
||||
return myechourl;
|
||||
}
|
||||
|
||||
public void setMyechourl(String myechourl) {
|
||||
this.myechourl = myechourl;
|
||||
}
|
||||
|
||||
public String getWebaddress() {
|
||||
return webaddress;
|
||||
}
|
||||
|
||||
public void setWebaddress(String webaddress) {
|
||||
this.webaddress = webaddress;
|
||||
}
|
||||
|
||||
public IpList getMqttaddress() {
|
||||
return mqttaddress;
|
||||
}
|
||||
|
||||
public void setMqttaddress(IpList mqttaddress) {
|
||||
this.mqttaddress = mqttaddress;
|
||||
}
|
||||
|
||||
public boolean isMqttconfigured() {
|
||||
return mqttconfigured;
|
||||
}
|
||||
|
||||
public void setMqttconfigured(boolean mqttconfigured) {
|
||||
this.mqttconfigured = mqttconfigured;
|
||||
}
|
||||
|
||||
public IpList getHassaddress() {
|
||||
return hassaddress;
|
||||
}
|
||||
|
||||
public void setHassaddress(IpList hassaddress) {
|
||||
this.hassaddress = hassaddress;
|
||||
}
|
||||
|
||||
public boolean isHassconfigured() {
|
||||
return hassconfigured;
|
||||
}
|
||||
|
||||
public void setHassconfigured(boolean hassconfigured) {
|
||||
this.hassconfigured = hassconfigured;
|
||||
}
|
||||
|
||||
public IpList getOpenhabaddress() {
|
||||
return openhabaddress;
|
||||
}
|
||||
|
||||
public void setOpenhabaddress(IpList openhabaddress) {
|
||||
this.openhabaddress = openhabaddress;
|
||||
}
|
||||
|
||||
public boolean isOpenhabconfigured() {
|
||||
return openhabconfigured;
|
||||
}
|
||||
|
||||
public void setOpenhabconfigured(boolean openhabconfigured) {
|
||||
this.openhabconfigured = openhabconfigured;
|
||||
}
|
||||
|
||||
public String getHubversion() {
|
||||
return hubversion;
|
||||
}
|
||||
|
||||
public void setHubversion(String hubversion) {
|
||||
this.hubversion = hubversion;
|
||||
}
|
||||
|
||||
public String getHubmac() {
|
||||
return hubmac;
|
||||
}
|
||||
|
||||
public void setHubmac(String hubmac) {
|
||||
this.hubmac = hubmac;
|
||||
}
|
||||
|
||||
public IpList getDomoticzaddress() {
|
||||
return domoticzaddress;
|
||||
}
|
||||
|
||||
public void setDomoticzaddress(IpList domoticzaddress) {
|
||||
this.domoticzaddress = domoticzaddress;
|
||||
}
|
||||
|
||||
public boolean isDomoticzconfigured() {
|
||||
return domoticzconfigured;
|
||||
}
|
||||
|
||||
public void setDomoticzconfigured(boolean domoticzconfigured) {
|
||||
this.domoticzconfigured = domoticzconfigured;
|
||||
}
|
||||
|
||||
public boolean isLifxconfigured() {
|
||||
return lifxconfigured;
|
||||
}
|
||||
|
||||
public void setLifxconfigured(boolean lifxconfigured) {
|
||||
this.lifxconfigured = lifxconfigured;
|
||||
}
|
||||
|
||||
public String getSecurityData() {
|
||||
return securityData;
|
||||
}
|
||||
|
||||
public void setSecurityData(String securityData) {
|
||||
this.securityData = securityData;
|
||||
}
|
||||
|
||||
public Integer getUpnpsenddelay() {
|
||||
return upnpsenddelay;
|
||||
}
|
||||
|
||||
public void setUpnpsenddelay(Integer upnpsenddelay) {
|
||||
this.upnpsenddelay = upnpsenddelay;
|
||||
}
|
||||
|
||||
public IpList getFhemaddress() {
|
||||
return fhemaddress;
|
||||
}
|
||||
|
||||
public void setFhemaddress(IpList fhemaddress) {
|
||||
this.fhemaddress = fhemaddress;
|
||||
}
|
||||
|
||||
public boolean isFhemconfigured() {
|
||||
return fhemconfigured;
|
||||
}
|
||||
|
||||
public void setFhemconfigured(boolean fhemconfigured) {
|
||||
this.fhemconfigured = fhemconfigured;
|
||||
}
|
||||
|
||||
// public List<NameValue> getActiveloggers() {
|
||||
// return activeloggers;
|
||||
// }
|
||||
// public void setActiveloggers(List<NameValue> activeloggers) {
|
||||
// this.activeloggers = activeloggers;
|
||||
// }
|
||||
public boolean isBroadlinkconfigured() {
|
||||
return broadlinkconfigured;
|
||||
}
|
||||
|
||||
public void setBroadlinkconfigured(boolean broadlinkconfigured) {
|
||||
this.broadlinkconfigured = broadlinkconfigured;
|
||||
}
|
||||
|
||||
public Boolean isValidVera() {
|
||||
if(this.getVeraAddress() == null || this.getVeraAddress().getDevices().size() <= 0)
|
||||
if (this.getVeraAddress() == null || this.getVeraAddress().getDevices().size() <= 0)
|
||||
return false;
|
||||
List<NamedIP> devicesList = this.getVeraAddress().getDevices();
|
||||
if(devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS))
|
||||
if (devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public Boolean isValidFibaro() {
|
||||
if(this.getFibaroAddress() == null || this.getFibaroAddress().getDevices().size() <= 0)
|
||||
if (this.getFibaroAddress() == null || this.getFibaroAddress().getDevices().size() <= 0)
|
||||
return false;
|
||||
List<NamedIP> devicesList = this.getFibaroAddress().getDevices();
|
||||
if(devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS))
|
||||
if (devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public Boolean isValidHarmony() {
|
||||
if(this.getHarmonyAddress() == null || this.getHarmonyAddress().getDevices().size() <= 0)
|
||||
return false;
|
||||
if (this.getHarmonyAddress() == null || this.getHarmonyAddress().getDevices().size() <= 0)
|
||||
return false;
|
||||
List<NamedIP> devicesList = this.getHarmonyAddress().getDevices();
|
||||
if(devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS))
|
||||
if (devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public Boolean isValidNest() {
|
||||
if(this.getNestpwd() == null || this.getNestpwd().equals(""))
|
||||
if (this.getNestpwd() == null || this.getNestpwd().equals(""))
|
||||
return false;
|
||||
if(this.getNestuser() == null || this.getNestuser().equals(""))
|
||||
if (this.getNestuser() == null || this.getNestuser().equals(""))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public Boolean isValidHue() {
|
||||
if(this.getHueaddress() == null || this.getHueaddress().getDevices().size() <= 0)
|
||||
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))
|
||||
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))
|
||||
if (this.getHaladdress() == null || this.getHaladdress().getDevices().size() <= 0)
|
||||
return false;
|
||||
if(devicesList.get(0).getPassword() == null || devicesList.get(0).getPassword().trim().isEmpty()) {
|
||||
if(this.getHaltoken() == null || this.getHaltoken().equals(""))
|
||||
List<NamedIP> devicesList = this.getHaladdress().getDevices();
|
||||
if (devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS))
|
||||
return false;
|
||||
if (devicesList.get(0).getPassword() == null || devicesList.get(0).getPassword().trim().isEmpty()) {
|
||||
if (this.getHaltoken() == null || this.getHaltoken().equals(""))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public Boolean isValidMQTT() {
|
||||
if(this.getMqttaddress() == null || this.getMqttaddress().getDevices().size() <= 0)
|
||||
return false;
|
||||
if (this.getMqttaddress() == null || this.getMqttaddress().getDevices().size() <= 0)
|
||||
return false;
|
||||
List<NamedIP> devicesList = this.getMqttaddress().getDevices();
|
||||
if(devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS))
|
||||
if (devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public Boolean isValidHass() {
|
||||
if(this.getHassaddress() == null || this.getHassaddress().getDevices().size() <= 0)
|
||||
return false;
|
||||
if (this.getHassaddress() == null || this.getHassaddress().getDevices().size() <= 0)
|
||||
return false;
|
||||
List<NamedIP> devicesList = this.getHassaddress().getDevices();
|
||||
if(devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS))
|
||||
if (devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public Boolean isValidDomoticz() {
|
||||
if(this.getDomoticzaddress() == null || this.getDomoticzaddress().getDevices().size() <= 0)
|
||||
return false;
|
||||
if (this.getDomoticzaddress() == null || this.getDomoticzaddress().getDevices().size() <= 0)
|
||||
return false;
|
||||
List<NamedIP> devicesList = this.getDomoticzaddress().getDevices();
|
||||
if(devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS))
|
||||
if (devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public Boolean isValidSomfy() {
|
||||
if(this.getSomfyAddress() == null || this.getSomfyAddress().getDevices().size() <= 0)
|
||||
if (this.getSomfyAddress() == null || this.getSomfyAddress().getDevices().size() <= 0)
|
||||
return false;
|
||||
List<NamedIP> devicesList = this.getSomfyAddress().getDevices();
|
||||
if(devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS))
|
||||
if (devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public Boolean isValidLifx() {
|
||||
return this.isLifxconfigured();
|
||||
}
|
||||
|
||||
public void updateHue(NamedIP aHue) {
|
||||
int indexHue = -1;
|
||||
for( int i = 0; i < hueaddress.getDevices().size(); i++) {
|
||||
if(hueaddress.getDevices().get(i).getName().equals(aHue.getName()))
|
||||
for (int i = 0; i < hueaddress.getDevices().size(); i++) {
|
||||
if (hueaddress.getDevices().get(i).getName().equals(aHue.getName()))
|
||||
indexHue = i;
|
||||
}
|
||||
if(indexHue >= 0) {
|
||||
if (indexHue >= 0) {
|
||||
hueaddress.getDevices().set(indexHue, aHue);
|
||||
this.setSettingsChanged(true);
|
||||
}
|
||||
}
|
||||
|
||||
public Boolean isValidHomeWizard() {
|
||||
if(this.getHomeWizardAddress() == null || this.getHomeWizardAddress().getDevices().size() <= 0)
|
||||
if (this.getHomeWizardAddress() == null || this.getHomeWizardAddress().getDevices().size() <= 0)
|
||||
return false;
|
||||
|
||||
|
||||
List<NamedIP> devicesList = this.getHomeWizardAddress().getDevices();
|
||||
if(devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS))
|
||||
if (devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS))
|
||||
return false;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public Boolean isValidOpenhab() {
|
||||
if (this.getOpenhabaddress() == null || this.getOpenhabaddress().getDevices().size() <= 0)
|
||||
return false;
|
||||
|
||||
List<NamedIP> devicesList = this.getOpenhabaddress().getDevices();
|
||||
if (devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public Boolean isValidFhem() {
|
||||
if (this.getFhemaddress() == null || this.getFhemaddress().getDevices().size() <= 0)
|
||||
return false;
|
||||
|
||||
List<NamedIP> devicesList = this.getFhemaddress().getDevices();
|
||||
if (devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public Boolean isValidBroadlink() {
|
||||
return this.isBroadlinkconfigured();
|
||||
}
|
||||
|
||||
public boolean isTracestate() {
|
||||
return tracestate;
|
||||
}
|
||||
|
||||
public void setTracestate(boolean tracestate) {
|
||||
this.tracestate = tracestate;
|
||||
}
|
||||
|
||||
public IpList getMoziotaddress() {
|
||||
return moziotaddress;
|
||||
}
|
||||
|
||||
public void setMoziotgaddress(IpList moziotgateway) {
|
||||
this.moziotaddress = moziotgateway;
|
||||
}
|
||||
|
||||
public Boolean isValidMozIot() {
|
||||
if (this.getMoziotaddress() == null || this.getMoziotaddress().getDevices().size() <= 0)
|
||||
return false;
|
||||
|
||||
List<NamedIP> devicesList = this.getMoziotaddress().getDevices();
|
||||
if (devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isMoziotconfigured() {
|
||||
return moziotconfigured;
|
||||
}
|
||||
|
||||
public void setMoziotconfigured(boolean moziotconfigured) {
|
||||
this.moziotconfigured = moziotconfigured;
|
||||
}
|
||||
|
||||
public boolean isUpnporiginal() {
|
||||
return upnporiginal;
|
||||
}
|
||||
|
||||
public void setUpnporiginal(boolean upnporiginal) {
|
||||
this.upnporiginal = upnporiginal;
|
||||
}
|
||||
|
||||
public Integer getSeedid() {
|
||||
return seedid;
|
||||
}
|
||||
|
||||
public void setSeedid(Integer seedid) {
|
||||
this.seedid = seedid;
|
||||
}
|
||||
|
||||
public IpList getHomegenieaddress() {
|
||||
return homegenieaddress;
|
||||
}
|
||||
|
||||
public void setHomegenieaddress(IpList homegenieaddress) {
|
||||
this.homegenieaddress = homegenieaddress;
|
||||
}
|
||||
|
||||
public boolean isHomegenieconfigured() {
|
||||
return homegenieconfigured;
|
||||
}
|
||||
|
||||
public void setHomegenieconfigured(boolean homegenieconfigured) {
|
||||
this.homegenieconfigured = homegenieconfigured;
|
||||
}
|
||||
public Boolean isValidHomeGenie() {
|
||||
if (this.getHomegenieaddress() == null || this.getHomegenieaddress().getDevices().size() <= 0)
|
||||
return false;
|
||||
|
||||
List<NamedIP> devicesList = this.getHomegenieaddress().getDevices();
|
||||
if (devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -14,4 +14,7 @@ public class Configuration {
|
||||
public static final String CONFIG_FILE = "data/habridge.config";
|
||||
public static final int NUMBER_OF_LOG_MESSAGES = 512;
|
||||
public static final long UPNP_NOTIFY_TIMEOUT = 20000;
|
||||
public static final int UPNP_SEND_DELAY = 650;
|
||||
public static final int BROADLINK_DISCOVER_PORT = 40000;
|
||||
public static final int BROADLINK_DISCONVER_TIMEOUT = 5000;
|
||||
}
|
||||
|
||||
@@ -31,6 +31,11 @@ public class DeviceMapTypes {
|
||||
public final static String[] DOMOTICZ_DEVICE = { "domoticzDevice", "Domoticz Device"};
|
||||
public final static String[] SOMFY_DEVICE = { "somfyDevice", "Somfy Device"};
|
||||
public final static String[] LIFX_DEVICE = { "lifxDevice", "LIFX Device"};
|
||||
public final static String[] OPENHAB_DEVICE = { "openhabDevice", "OpenHAB Device"};
|
||||
public final static String[] FHEM_DEVICE = { "fhemDevice", "FHEM Device"};
|
||||
public final static String[] BROADLINK_DEVICE = { "broadlinkDevice", "Broadlink Device"};
|
||||
public final static String[] MOZIOT_DEVICE = { "moziotDevice", "Mozilla IOT Device"};
|
||||
public final static String[] HOMEGENIE_DEVICE = { "homegenieDevice", "HomeGenie Device"};
|
||||
|
||||
public final static int typeIndex = 0;
|
||||
public final static int displayIndex = 1;
|
||||
@@ -56,7 +61,6 @@ public class DeviceMapTypes {
|
||||
deviceMapTypes.add(MQTT_MESSAGE);
|
||||
deviceMapTypes.add(NEST_HOMEAWAY);
|
||||
deviceMapTypes.add(NEST_THERMO_SET);
|
||||
deviceMapTypes.add(SOMFY_DEVICE);
|
||||
deviceMapTypes.add(TCP_DEVICE);
|
||||
deviceMapTypes.add(UDP_DEVICE);
|
||||
deviceMapTypes.add(VERA_DEVICE);
|
||||
@@ -64,6 +68,11 @@ public class DeviceMapTypes {
|
||||
deviceMapTypes.add(FIBARO_DEVICE);
|
||||
deviceMapTypes.add(FIBARO_SCENE);
|
||||
deviceMapTypes.add(SOMFY_DEVICE);
|
||||
deviceMapTypes.add(OPENHAB_DEVICE);
|
||||
deviceMapTypes.add(FHEM_DEVICE);
|
||||
deviceMapTypes.add(BROADLINK_DEVICE);
|
||||
deviceMapTypes.add(MOZIOT_DEVICE);
|
||||
deviceMapTypes.add(HOMEGENIE_DEVICE);
|
||||
}
|
||||
public static int getTypeIndex() {
|
||||
return typeIndex;
|
||||
|
||||
@@ -44,19 +44,19 @@ public class HABridge {
|
||||
Version theVersion;
|
||||
@SuppressWarnings("unused")
|
||||
HttpClientPool thePool;
|
||||
|
||||
ShutdownHook shutdownHook = null;
|
||||
|
||||
log.info("HA Bridge startup sequence...");
|
||||
theVersion = new Version();
|
||||
// Singleton initialization
|
||||
thePool = new HttpClientPool();
|
||||
|
||||
log.info("HA Bridge (v" + theVersion.getVersion() + ") starting....");
|
||||
|
||||
bridgeSettings = new BridgeSettings();
|
||||
// sparkjava config directive to set html static file location for Jetty
|
||||
while(!bridgeSettings.getBridgeControl().isStop()) {
|
||||
bridgeSettings.buildSettings();
|
||||
bridgeSettings.getBridgeSecurity().removeTestUsers();
|
||||
log.info("HA Bridge initializing....");
|
||||
log.info("HA Bridge (v{}) initializing....", theVersion.getVersion() );
|
||||
// sparkjava config directive to set ip address for the web server to listen on
|
||||
ipAddress(bridgeSettings.getBridgeSettingsDescriptor().getWebaddress());
|
||||
// sparkjava config directive to set port for the web server to listen on
|
||||
@@ -69,6 +69,14 @@ public class HABridge {
|
||||
// setup system control api first
|
||||
theSystem = new SystemControl(bridgeSettings, theVersion);
|
||||
theSystem.setupServer();
|
||||
|
||||
// Add shutdown hook to be able to properly stop server
|
||||
if (shutdownHook != null) {
|
||||
Runtime.getRuntime().removeShutdownHook(shutdownHook);
|
||||
}
|
||||
shutdownHook = new ShutdownHook(bridgeSettings, theSystem);
|
||||
Runtime.getRuntime().addShutdownHook(shutdownHook);
|
||||
|
||||
// setup the UDP Datagram socket to be used by the HueMulator and the upnpListener
|
||||
udpSender = UDPDatagramSender.createUDPDatagramSender(bridgeSettings.getBridgeSettingsDescriptor().getUpnpResponsePort());
|
||||
if(udpSender == null) {
|
||||
@@ -86,12 +94,15 @@ public class HABridge {
|
||||
// wait for the sparkjava initialization of the rest api classes to be complete
|
||||
awaitInitialization();
|
||||
|
||||
if(bridgeSettings.getBridgeSettingsDescriptor().isTraceupnp())
|
||||
log.info("Traceupnp: upnp config address: " + bridgeSettings.getBridgeSettingsDescriptor().getUpnpConfigAddress() + "-useIface:" +
|
||||
bridgeSettings.getBridgeSettingsDescriptor().isUseupnpiface() + " on web server: " +
|
||||
bridgeSettings.getBridgeSettingsDescriptor().getWebaddress() + ":" + bridgeSettings.getBridgeSettingsDescriptor().getServerPort());
|
||||
if(bridgeSettings.getBridgeSettingsDescriptor().isTraceupnp()) {
|
||||
log.info("Traceupnp: upnp config address: {} -useIface: {} on web server: {}:{}",
|
||||
bridgeSettings.getBridgeSettingsDescriptor().getUpnpConfigAddress(),
|
||||
bridgeSettings.getBridgeSettingsDescriptor().isUseupnpiface(),
|
||||
bridgeSettings.getBridgeSettingsDescriptor().getWebaddress(),
|
||||
bridgeSettings.getBridgeSettingsDescriptor().getServerPort());
|
||||
}
|
||||
// setup the class to handle the upnp response rest api
|
||||
theSettingResponder = new UpnpSettingsResource(bridgeSettings.getBridgeSettingsDescriptor());
|
||||
theSettingResponder = new UpnpSettingsResource(bridgeSettings);
|
||||
theSettingResponder.setupServer();
|
||||
|
||||
// start the upnp ssdp discovery listener
|
||||
@@ -103,7 +114,7 @@ public class HABridge {
|
||||
theUpnpListener = null;
|
||||
}
|
||||
if(theUpnpListener != null && theUpnpListener.startListening())
|
||||
log.info("HA Bridge (v" + theVersion.getVersion() + ") reinitialization requessted....");
|
||||
log.info("HA Bridge (v{}) reinitialization requessted....", theVersion.getVersion());
|
||||
else
|
||||
bridgeSettings.getBridgeControl().setStop(true);
|
||||
if(bridgeSettings.getBridgeSettingsDescriptor().isSettingsChanged())
|
||||
@@ -118,7 +129,7 @@ public class HABridge {
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
} catch (InterruptedException e) {
|
||||
log.error("Sleep error: " + e.getMessage());
|
||||
log.error("Sleep error: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -127,19 +138,19 @@ public class HABridge {
|
||||
bridgeSettings.updateConfigFile();
|
||||
try {
|
||||
HttpClientPool.shutdown();
|
||||
thePool = null;
|
||||
} catch (InterruptedException e) {
|
||||
log.warn("Error shutting down http pool: " + e.getMessage());;
|
||||
log.warn("Error shutting down http pool: {}", e.getMessage());;
|
||||
} catch (IOException e) {
|
||||
log.warn("Error shutting down http pool: " + e.getMessage());;
|
||||
log.warn("Error shutting down http pool: {}", e.getMessage());;
|
||||
}
|
||||
log.info("HA Bridge (v" + theVersion.getVersion() + ") exiting....");
|
||||
thePool = null;
|
||||
log.info("HA Bridge (v{}) exiting....", theVersion.getVersion());
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
private static void theExceptionHandler(Exception e, Integer thePort) {
|
||||
Logger log = LoggerFactory.getLogger(HABridge.class);
|
||||
log.error("Could not start ha-bridge webservice on port [" + thePort + "] due to: " + e.getMessage());
|
||||
log.error("Could not start ha-bridge webservice on port [{}] due to: {}", thePort, e.getMessage());
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,8 +9,10 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.bwssystems.HABridge.devicemanagmeent.ResourceHandler;
|
||||
import com.bwssystems.HABridge.plugins.NestBridge.NestHome;
|
||||
import com.bwssystems.HABridge.plugins.broadlink.BroadlinkHome;
|
||||
import com.bwssystems.HABridge.plugins.domoticz.DomoticzHome;
|
||||
import com.bwssystems.HABridge.plugins.exec.CommandHome;
|
||||
import com.bwssystems.HABridge.plugins.fhem.FHEMHome;
|
||||
import com.bwssystems.HABridge.plugins.hal.HalHome;
|
||||
import com.bwssystems.HABridge.plugins.harmony.HarmonyHome;
|
||||
import com.bwssystems.HABridge.plugins.hass.HassHome;
|
||||
@@ -18,12 +20,15 @@ import com.bwssystems.HABridge.plugins.homewizard.HomeWizardHome;
|
||||
import com.bwssystems.HABridge.plugins.http.HTTPHome;
|
||||
import com.bwssystems.HABridge.plugins.hue.HueHome;
|
||||
import com.bwssystems.HABridge.plugins.lifx.LifxHome;
|
||||
import com.bwssystems.HABridge.plugins.moziot.MozIotHome;
|
||||
import com.bwssystems.HABridge.plugins.mqtt.MQTTHome;
|
||||
import com.bwssystems.HABridge.plugins.openhab.OpenHABHome;
|
||||
import com.bwssystems.HABridge.plugins.somfy.SomfyHome;
|
||||
import com.bwssystems.HABridge.plugins.tcp.TCPHome;
|
||||
import com.bwssystems.HABridge.plugins.udp.UDPHome;
|
||||
import com.bwssystems.HABridge.plugins.vera.VeraHome;
|
||||
import com.bwssystems.HABridge.plugins.fibaro.FibaroHome;
|
||||
import com.bwssystems.HABridge.plugins.homegenie.HomeGenieHome;
|
||||
import com.bwssystems.HABridge.util.UDPDatagramSender;
|
||||
|
||||
public class HomeManager {
|
||||
@@ -39,6 +44,14 @@ public class HomeManager {
|
||||
// factory method
|
||||
public void buildHomes(BridgeSettings bridgeSettings, UDPDatagramSender aUdpDatagramSender) {
|
||||
Home aHome = null;
|
||||
//setup the http handler Home - This must be the first home created for devMode
|
||||
aHome = new HTTPHome(bridgeSettings);
|
||||
homeList.put(DeviceMapTypes.HTTP_DEVICE[DeviceMapTypes.typeIndex], aHome);
|
||||
homeList.put(DeviceMapTypes.CUSTOM_DEVICE[DeviceMapTypes.typeIndex], aHome);
|
||||
homeList.put(DeviceMapTypes.VERA_DEVICE[DeviceMapTypes.typeIndex], aHome);
|
||||
homeList.put(DeviceMapTypes.VERA_SCENE[DeviceMapTypes.typeIndex], aHome);
|
||||
homeList.put(DeviceMapTypes.FIBARO_DEVICE[DeviceMapTypes.typeIndex], aHome);
|
||||
homeList.put(DeviceMapTypes.FIBARO_SCENE[DeviceMapTypes.typeIndex], aHome);
|
||||
//setup the harmony connection if available
|
||||
aHome = new HarmonyHome(bridgeSettings);
|
||||
resourceList.put(DeviceMapTypes.HARMONY_ACTIVITY[DeviceMapTypes.typeIndex], aHome);
|
||||
@@ -77,14 +90,6 @@ public class HomeManager {
|
||||
aHome = new CommandHome(bridgeSettings);
|
||||
homeList.put(DeviceMapTypes.EXEC_DEVICE_COMPAT[DeviceMapTypes.typeIndex], aHome);
|
||||
homeList.put(DeviceMapTypes.CMD_DEVICE[DeviceMapTypes.typeIndex], aHome);
|
||||
//setup the http handler Home
|
||||
aHome = new HTTPHome(bridgeSettings);
|
||||
homeList.put(DeviceMapTypes.HTTP_DEVICE[DeviceMapTypes.typeIndex], aHome);
|
||||
homeList.put(DeviceMapTypes.CUSTOM_DEVICE[DeviceMapTypes.typeIndex], aHome);
|
||||
homeList.put(DeviceMapTypes.VERA_DEVICE[DeviceMapTypes.typeIndex], aHome);
|
||||
homeList.put(DeviceMapTypes.VERA_SCENE[DeviceMapTypes.typeIndex], aHome);
|
||||
homeList.put(DeviceMapTypes.FIBARO_DEVICE[DeviceMapTypes.typeIndex], aHome);
|
||||
homeList.put(DeviceMapTypes.FIBARO_SCENE[DeviceMapTypes.typeIndex], aHome);
|
||||
//setup the tcp handler Home
|
||||
aHome = new TCPHome(bridgeSettings);
|
||||
homeList.put(DeviceMapTypes.TCP_DEVICE[DeviceMapTypes.typeIndex], aHome);
|
||||
@@ -105,7 +110,7 @@ public class HomeManager {
|
||||
aHome = new DomoticzHome(bridgeSettings);
|
||||
homeList.put(DeviceMapTypes.DOMOTICZ_DEVICE[DeviceMapTypes.typeIndex], aHome);
|
||||
resourceList.put(DeviceMapTypes.DOMOTICZ_DEVICE[DeviceMapTypes.typeIndex], aHome);
|
||||
//setup the Somfy configuration if available
|
||||
//setup the Somfy configuration if availableOPENHAB
|
||||
aHome = new SomfyHome(bridgeSettings);
|
||||
homeList.put(DeviceMapTypes.SOMFY_DEVICE[DeviceMapTypes.typeIndex], aHome);
|
||||
resourceList.put(DeviceMapTypes.SOMFY_DEVICE[DeviceMapTypes.typeIndex], aHome);
|
||||
@@ -113,6 +118,26 @@ public class HomeManager {
|
||||
aHome = new LifxHome(bridgeSettings);
|
||||
resourceList.put(DeviceMapTypes.LIFX_DEVICE[DeviceMapTypes.typeIndex], aHome);
|
||||
homeList.put(DeviceMapTypes.LIFX_DEVICE[DeviceMapTypes.typeIndex], aHome);
|
||||
//setup the OpenHAB configuration if available
|
||||
aHome = new OpenHABHome(bridgeSettings);
|
||||
resourceList.put(DeviceMapTypes.OPENHAB_DEVICE[DeviceMapTypes.typeIndex], aHome);
|
||||
homeList.put(DeviceMapTypes.OPENHAB_DEVICE[DeviceMapTypes.typeIndex], aHome);
|
||||
//setup the FHEM configuration if available
|
||||
aHome = new FHEMHome(bridgeSettings);
|
||||
resourceList.put(DeviceMapTypes.FHEM_DEVICE[DeviceMapTypes.typeIndex], aHome);
|
||||
homeList.put(DeviceMapTypes.FHEM_DEVICE[DeviceMapTypes.typeIndex], aHome);
|
||||
//setup the Broadlink configuration if available
|
||||
aHome = new BroadlinkHome(bridgeSettings);
|
||||
resourceList.put(DeviceMapTypes.BROADLINK_DEVICE[DeviceMapTypes.typeIndex], aHome);
|
||||
homeList.put(DeviceMapTypes.BROADLINK_DEVICE[DeviceMapTypes.typeIndex], aHome);
|
||||
//setup the Mozilla IOT configuration if available
|
||||
aHome = new MozIotHome(bridgeSettings);
|
||||
resourceList.put(DeviceMapTypes.MOZIOT_DEVICE[DeviceMapTypes.typeIndex], aHome);
|
||||
homeList.put(DeviceMapTypes.MOZIOT_DEVICE[DeviceMapTypes.typeIndex], aHome);
|
||||
//setup the HomeGenie configuration if available
|
||||
aHome = new HomeGenieHome(bridgeSettings);
|
||||
resourceList.put(DeviceMapTypes.HOMEGENIE_DEVICE[DeviceMapTypes.typeIndex], aHome);
|
||||
homeList.put(DeviceMapTypes.HOMEGENIE_DEVICE[DeviceMapTypes.typeIndex], aHome);
|
||||
}
|
||||
|
||||
public Home findHome(String type) {
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
package com.bwssystems.HABridge;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
|
||||
public class NamedIP {
|
||||
private String name;
|
||||
private String ip;
|
||||
@@ -7,48 +11,103 @@ public class NamedIP {
|
||||
private String port;
|
||||
private String username;
|
||||
private String password;
|
||||
private JsonObject extensions;
|
||||
private Boolean secure;
|
||||
|
||||
private String httpPreamble;
|
||||
private String encodedLogin;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getIp() {
|
||||
return ip;
|
||||
}
|
||||
|
||||
public void setIp(String ip) {
|
||||
this.ip = ip;
|
||||
}
|
||||
public String getWebhook() {
|
||||
return webhook;
|
||||
}
|
||||
public void setWebhook(final String webhook) {
|
||||
this.webhook = webhook;
|
||||
}
|
||||
public String getPort() {
|
||||
|
||||
public String getWebhook() {
|
||||
return webhook;
|
||||
}
|
||||
|
||||
public void setWebhook(final String webhook) {
|
||||
this.webhook = webhook;
|
||||
}
|
||||
|
||||
public String getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public void setPort(String port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public Boolean getSecure() {
|
||||
return secure;
|
||||
}
|
||||
|
||||
public void setSecure(Boolean secure) {
|
||||
this.secure = secure;
|
||||
}
|
||||
|
||||
public JsonObject getExtensions() {
|
||||
return extensions;
|
||||
}
|
||||
|
||||
public void setExtensions(JsonObject extensions) {
|
||||
this.extensions = extensions;
|
||||
}
|
||||
|
||||
public String getHttpPreamble() {
|
||||
if (httpPreamble == null || !httpPreamble.trim().isEmpty()) {
|
||||
if (getSecure() != null && getSecure())
|
||||
httpPreamble = "https://";
|
||||
else
|
||||
httpPreamble = "http://";
|
||||
|
||||
httpPreamble = httpPreamble + getIp();
|
||||
if (getPort() != null && !getPort().trim().isEmpty()) {
|
||||
httpPreamble = httpPreamble + ":" + getPort();
|
||||
}
|
||||
}
|
||||
return httpPreamble;
|
||||
}
|
||||
|
||||
public void setHttpPreamble(String httpPreamble) {
|
||||
this.httpPreamble = httpPreamble;
|
||||
}
|
||||
|
||||
public String getUserPass64() {
|
||||
if (encodedLogin == null || !encodedLogin.trim().isEmpty()) {
|
||||
if (getUsername() != null && !getUsername().isEmpty() && getPassword() != null
|
||||
&& !getPassword().isEmpty()) {
|
||||
String userPass = getUsername() + ":" + getPassword();
|
||||
encodedLogin = new String(Base64.encodeBase64(userPass.getBytes()));
|
||||
}
|
||||
}
|
||||
|
||||
return encodedLogin;
|
||||
}
|
||||
}
|
||||
|
||||
48
src/main/java/com/bwssystems/HABridge/ShutdownHook.java
Normal file
48
src/main/java/com/bwssystems/HABridge/ShutdownHook.java
Normal file
@@ -0,0 +1,48 @@
|
||||
package com.bwssystems.HABridge;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* This class implements the shutdown hook used to properly stop server from the
|
||||
* command line (sending SIGTERM), or while shutting down the host machine.
|
||||
*
|
||||
* @author gaudryc
|
||||
*/
|
||||
public class ShutdownHook extends Thread {
|
||||
|
||||
private final BridgeSettings bridgeSettings;
|
||||
private final SystemControl theSystem;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param bridgeSettings
|
||||
* bridge settings
|
||||
* @param theSystem
|
||||
*/
|
||||
public ShutdownHook(final BridgeSettings bridgeSettings, final SystemControl theSystem) {
|
||||
this.bridgeSettings = bridgeSettings;
|
||||
this.theSystem = theSystem;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Logger log = LoggerFactory.getLogger(ShutdownHook.class);
|
||||
log.info("Shutdown requested...");
|
||||
if (bridgeSettings != null) {
|
||||
if (!bridgeSettings.getBridgeControl().isStop() && (theSystem != null)) {
|
||||
log.info("Forcing system stop...");
|
||||
theSystem.stop();
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
} catch (InterruptedException e) {
|
||||
log.error("Sleep error: " + e.getMessage());
|
||||
}
|
||||
} else {
|
||||
log.info("Already stopped");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,15 +14,19 @@ import java.net.InetAddress;
|
||||
import java.net.MulticastSocket;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
//import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Timer;
|
||||
import java.util.Base64;
|
||||
//import java.util.Iterator;
|
||||
//import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
//import com.bwssystems.HABridge.api.NameValue;
|
||||
import com.bwssystems.HABridge.api.hue.WhitelistEntry;
|
||||
import com.bwssystems.HABridge.dao.BackupFilename;
|
||||
import com.bwssystems.HABridge.util.JsonTransformer;
|
||||
@@ -36,6 +40,7 @@ import com.google.gson.reflect.TypeToken;
|
||||
import ch.qos.logback.classic.LoggerContext;
|
||||
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||
import ch.qos.logback.classic.spi.LoggingEvent;
|
||||
//import ch.qos.logback.core.Appender;
|
||||
import ch.qos.logback.core.read.CyclicBufferAppender;
|
||||
|
||||
public class SystemControl {
|
||||
@@ -55,7 +60,7 @@ public class SystemControl {
|
||||
this.version = theVersion;
|
||||
this.lc = (LoggerContext) LoggerFactory.getILoggerFactory();
|
||||
this.dateFormat = new SimpleDateFormat("MM-dd-yyyy HH:mm:ss.SSS");
|
||||
reacquireCBA();
|
||||
setupLoggerSettings();
|
||||
theLogServiceMgr = new LoggingManager();
|
||||
theLogServiceMgr.init();
|
||||
}
|
||||
@@ -88,7 +93,7 @@ public class SystemControl {
|
||||
String logMsgs;
|
||||
int count = -1;
|
||||
if(cyclicBufferAppender == null)
|
||||
reacquireCBA();
|
||||
setupLoggerSettings();
|
||||
if (cyclicBufferAppender != null) {
|
||||
count = cyclicBufferAppender.getLength();
|
||||
}
|
||||
@@ -238,6 +243,24 @@ public class SystemControl {
|
||||
return result;
|
||||
}, new JsonTransformer());
|
||||
|
||||
// http://ip_address:port/system/logout CORS request
|
||||
options(SYSTEM_CONTEXT + "/logout", (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/logout invalidates user session
|
||||
put(SYSTEM_CONTEXT + "/logout", (request, response) -> {
|
||||
log.debug("logout....");
|
||||
bridgeSettings.getBridgeSecurity().removeAuthenticatedUser(request);
|
||||
response.status(HttpStatus.SC_OK);
|
||||
response.type("application/json");
|
||||
return "";
|
||||
});
|
||||
|
||||
// http://ip_address:port/system/presslinkbutton CORS request
|
||||
options(SYSTEM_CONTEXT + "/presslinkbutton", (request, response) -> {
|
||||
response.status(HttpStatus.SC_OK);
|
||||
@@ -356,6 +379,8 @@ public class SystemControl {
|
||||
log.debug("bridge settings requested from " + request.ip());
|
||||
response.status(HttpStatus.SC_OK);
|
||||
response.type("application/json");
|
||||
// if(bridgeSettings.getBridgeSettingsDescriptor().getActiveloggers() == null)
|
||||
// bridgeSettings.getBridgeSettingsDescriptor().setActiveloggers(getLogAppenders());
|
||||
return bridgeSettings.getBridgeSettingsDescriptor();
|
||||
}, new JsonTransformer());
|
||||
|
||||
@@ -372,6 +397,8 @@ public class SystemControl {
|
||||
put(SYSTEM_CONTEXT + "/settings", (request, response) -> {
|
||||
log.debug("save bridge settings requested from " + request.ip() + " with body: " + request.body());
|
||||
BridgeSettingsDescriptor newBridgeSettings = new Gson().fromJson(request.body(), BridgeSettingsDescriptor.class);
|
||||
if(newBridgeSettings.getUpnpsenddelay() > 15000)
|
||||
newBridgeSettings.setUpnpsenddelay(15000);
|
||||
bridgeSettings.save(newBridgeSettings);
|
||||
response.status(HttpStatus.SC_OK);
|
||||
response.type("application/json");
|
||||
@@ -482,11 +509,42 @@ public class SystemControl {
|
||||
}, new JsonTransformer());
|
||||
}
|
||||
|
||||
void reacquireCBA() {
|
||||
cyclicBufferAppender = (CyclicBufferAppender<ILoggingEvent>) lc.getLogger(
|
||||
private void setupLoggerSettings() {
|
||||
// final ch.qos.logback.classic.Logger logger = lc.getLogger(Logger.ROOT_LOGGER_NAME);
|
||||
|
||||
cyclicBufferAppender = (CyclicBufferAppender<ILoggingEvent>) lc.getLogger(
|
||||
Logger.ROOT_LOGGER_NAME).getAppender(CYCLIC_BUFFER_APPENDER_NAME);
|
||||
cyclicBufferAppender.setMaxSize(bridgeSettings.getBridgeSettingsDescriptor().getNumberoflogmessages());
|
||||
}
|
||||
// if(bridgeSettings.getBridgeSettingsDescriptor().getActiveloggers() != null) {
|
||||
// for (NameValue temp : bridgeSettings.getBridgeSettingsDescriptor().getActiveloggers()) {
|
||||
// if(temp.getValue().equals("false"))
|
||||
// logger.detachAppender(temp.getName());
|
||||
// }
|
||||
//
|
||||
// }
|
||||
}
|
||||
|
||||
// private List<NameValue> getLogAppenders() {
|
||||
// final ch.qos.logback.classic.Logger logger = lc.getLogger(Logger.ROOT_LOGGER_NAME);
|
||||
//
|
||||
// final Iterator<Appender<ILoggingEvent>> it = logger.iteratorForAppenders();
|
||||
//
|
||||
// List<NameValue> theLoggers = new ArrayList<NameValue>();
|
||||
//
|
||||
// while (it.hasNext()) {
|
||||
//
|
||||
// final Appender<ILoggingEvent> appender = it.next();
|
||||
//
|
||||
// if (!(appender instanceof CyclicBufferAppender)) {
|
||||
// NameValue theLogger = new NameValue();
|
||||
// theLogger.setName(appender.getName());
|
||||
// theLogger.setValue("true");
|
||||
// theLoggers.add(theLogger);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return theLoggers;
|
||||
// }
|
||||
|
||||
protected void pingListener() {
|
||||
try {
|
||||
@@ -518,4 +576,5 @@ public class SystemControl {
|
||||
pingListener();
|
||||
return "{\"control\":\"stopping\"}";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,14 +1,14 @@
|
||||
package com.bwssystems.HABridge.api.hue;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
public class WhitelistEntry
|
||||
{
|
||||
private String lastUseDate;
|
||||
private String createDate;
|
||||
private String name;
|
||||
private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
|
||||
private static final DateTimeFormatter dateTimeFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
|
||||
|
||||
public static WhitelistEntry createEntry(String devicetype) {
|
||||
WhitelistEntry anEntry = new WhitelistEntry();
|
||||
@@ -18,9 +18,9 @@ public class WhitelistEntry
|
||||
return anEntry;
|
||||
}
|
||||
|
||||
public static String getCurrentDate() {
|
||||
return dateFormat.format(new Date());
|
||||
}
|
||||
public static String getCurrentDate() {
|
||||
return LocalDateTime.now().format(dateTimeFormat);
|
||||
}
|
||||
|
||||
public String getLastUseDate() {
|
||||
return lastUseDate;
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.bwssystems.HABridge.dao;
|
||||
|
||||
public class BackupFilename {
|
||||
private String filename;
|
||||
private String file;
|
||||
|
||||
public String getFilename() {
|
||||
return filename;
|
||||
@@ -10,4 +11,13 @@ public class BackupFilename {
|
||||
public void setFilename(String filename) {
|
||||
this.filename = filename;
|
||||
}
|
||||
|
||||
public String getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
public void setFile(String file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -80,7 +80,16 @@ public class DeviceDescriptor{
|
||||
@SerializedName("deviceState")
|
||||
@Expose
|
||||
private DeviceState deviceState;
|
||||
|
||||
@SerializedName("onFirstDim")
|
||||
@Expose
|
||||
private boolean onFirstDim;
|
||||
@SerializedName("onWhenDimPresent")
|
||||
@Expose
|
||||
private boolean onWhenDimPresent;
|
||||
@SerializedName("lockDeviceId")
|
||||
@Expose
|
||||
private boolean lockDeviceId;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
@@ -275,6 +284,22 @@ public class DeviceDescriptor{
|
||||
this.comments = comments;
|
||||
}
|
||||
|
||||
public boolean isOnFirstDim() {
|
||||
return onFirstDim;
|
||||
}
|
||||
|
||||
public void setOnFirstDim(boolean onFirstDim) {
|
||||
this.onFirstDim = onFirstDim;
|
||||
}
|
||||
|
||||
public boolean isOnWhenDimPresent() {
|
||||
return onWhenDimPresent;
|
||||
}
|
||||
|
||||
public void setOnWhenDimPresent(boolean onWhenDimPresent) {
|
||||
this.onWhenDimPresent = onWhenDimPresent;
|
||||
}
|
||||
|
||||
public boolean containsType(String aType) {
|
||||
if(aType == null)
|
||||
return false;
|
||||
@@ -311,4 +336,12 @@ public class DeviceDescriptor{
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
public boolean isLockDeviceId() {
|
||||
return lockDeviceId;
|
||||
}
|
||||
|
||||
public void setLockDeviceId(boolean lockDeviceId) {
|
||||
this.lockDeviceId = lockDeviceId;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,6 @@
|
||||
package com.bwssystems.HABridge.dao;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
@@ -13,18 +11,18 @@ import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.xml.bind.DatatypeConverter;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.bwssystems.HABridge.DeviceMapTypes;
|
||||
import com.bwssystems.HABridge.api.CallItem;
|
||||
import com.bwssystems.HABridge.api.hue.DeviceResponse;
|
||||
import com.bwssystems.HABridge.api.hue.DeviceState;
|
||||
import com.bwssystems.HABridge.dao.DeviceDescriptor;
|
||||
import com.bwssystems.HABridge.plugins.hue.HueHome;
|
||||
import com.bwssystems.HABridge.util.BackupHandler;
|
||||
import com.bwssystems.HABridge.util.JsonTransformer;
|
||||
import com.bwssystems.HABridge.util.HexLibrary;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
@@ -39,45 +37,47 @@ import java.util.Arrays;
|
||||
*/
|
||||
public class DeviceRepository extends BackupHandler {
|
||||
private Map<String, DeviceDescriptor> devices;
|
||||
private Path repositoryPath;
|
||||
private Path repositoryPath;
|
||||
private Gson gson;
|
||||
private Integer nextId;
|
||||
private Logger log = LoggerFactory.getLogger(DeviceRepository.class);
|
||||
|
||||
public DeviceRepository(String deviceDb) {
|
||||
private Integer nextId;
|
||||
private Integer seedId;
|
||||
private Logger log = LoggerFactory.getLogger(DeviceRepository.class);
|
||||
|
||||
public DeviceRepository(String deviceDb, Integer seedid) {
|
||||
super();
|
||||
gson =
|
||||
new GsonBuilder()
|
||||
.excludeFieldsWithoutExposeAnnotation()
|
||||
.create();
|
||||
gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
|
||||
repositoryPath = null;
|
||||
repositoryPath = Paths.get(deviceDb);
|
||||
setupParams(repositoryPath, ".bk", "device.db-");
|
||||
nextId = 0;
|
||||
nextId = seedid;
|
||||
seedId = seedid;
|
||||
_loadRepository(repositoryPath);
|
||||
}
|
||||
|
||||
public void loadRepository() {
|
||||
if(repositoryPath != null)
|
||||
_loadRepository(repositoryPath);
|
||||
}
|
||||
private void _loadRepository(Path aPath){
|
||||
|
||||
public void loadRepository() {
|
||||
if (repositoryPath != null)
|
||||
_loadRepository(repositoryPath);
|
||||
}
|
||||
|
||||
private void _loadRepository(Path aPath) {
|
||||
String jsonContent = repositoryReader(aPath);
|
||||
devices = new HashMap<String, DeviceDescriptor>();
|
||||
|
||||
if(jsonContent != null)
|
||||
{
|
||||
|
||||
if (jsonContent != null) {
|
||||
DeviceDescriptor list[] = gson.fromJson(jsonContent, DeviceDescriptor[].class);
|
||||
for(int i = 0; i < list.length; i++) {
|
||||
list[i].setDeviceState(null);
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
if (list[i].getColorUrl() == null || list[i].getColorUrl().isEmpty())
|
||||
list[i].setDeviceState(DeviceState.createDeviceState(false));
|
||||
else
|
||||
list[i].setDeviceState(DeviceState.createDeviceState(true));
|
||||
put(list[i].getId(), list[i]);
|
||||
if(Integer.decode(list[i].getId()) > nextId) {
|
||||
if (Integer.decode(list[i].getId()) > nextId) {
|
||||
nextId = Integer.decode(list[i].getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public List<DeviceDescriptor> findAll() {
|
||||
List<DeviceDescriptor> list = new ArrayList<DeviceDescriptor>(devices.values());
|
||||
return list;
|
||||
@@ -85,8 +85,8 @@ public class DeviceRepository extends BackupHandler {
|
||||
|
||||
public List<DeviceDescriptor> findActive() {
|
||||
List<DeviceDescriptor> list = new ArrayList<DeviceDescriptor>();
|
||||
for(DeviceDescriptor aDevice : new ArrayList<DeviceDescriptor>(devices.values())) {
|
||||
if(!aDevice.isInactive())
|
||||
for (DeviceDescriptor aDevice : new ArrayList<DeviceDescriptor>(devices.values())) {
|
||||
if (!aDevice.isInactive())
|
||||
list.add(aDevice);
|
||||
}
|
||||
return list;
|
||||
@@ -103,12 +103,12 @@ public class DeviceRepository extends BackupHandler {
|
||||
DeviceDescriptor theDevice;
|
||||
String theRequesterAddress;
|
||||
|
||||
HashMap<String,String > addressMap;
|
||||
HashMap<String, String> addressMap;
|
||||
while (anIterator.hasNext()) {
|
||||
theDevice = anIterator.next();
|
||||
theRequesterAddress = theDevice.getRequesterAddress();
|
||||
addressMap = new HashMap<String, String>();
|
||||
if(theRequesterAddress != null) {
|
||||
if (theRequesterAddress != null) {
|
||||
if (theRequesterAddress.contains(",")) {
|
||||
String[] theArray = theRequesterAddress.split(",");
|
||||
for (String v : theArray) {
|
||||
@@ -123,155 +123,167 @@ public class DeviceRepository extends BackupHandler {
|
||||
return theReturnList;
|
||||
}
|
||||
|
||||
public Map<String, DeviceResponse> findAllByGroupWithState(String[] lightsInGroup, String anAddress, HueHome myHueHome, Gson aGsonBuilder) {
|
||||
public Map<String, DeviceResponse> findAllByGroupWithState(String[] lightsInGroup, String anAddress,
|
||||
HueHome myHueHome, Gson aGsonBuilder) {
|
||||
return findAllByGroupWithState(lightsInGroup, anAddress, myHueHome, aGsonBuilder, false);
|
||||
}
|
||||
|
||||
public Map<String, DeviceResponse> findAllByGroupWithState(String[] lightsInGroup, String anAddress, HueHome myHueHome, Gson aGsonBuilder, boolean ignoreAddress) {
|
||||
public Map<String, DeviceResponse> findAllByGroupWithState(String[] lightsInGroup, String anAddress,
|
||||
HueHome myHueHome, Gson aGsonBuilder, boolean ignoreAddress) {
|
||||
Map<String, DeviceResponse> deviceResponseMap = new HashMap<String, DeviceResponse>();
|
||||
Map<String, DeviceDescriptor> lights = new HashMap<String, DeviceDescriptor>(devices);
|
||||
lights.keySet().retainAll(Arrays.asList(lightsInGroup));
|
||||
for (DeviceDescriptor light : (ignoreAddress ? lights.values() : findAllByRequester(anAddress, lights.values()))) {
|
||||
for (DeviceDescriptor light : (ignoreAddress ? lights.values()
|
||||
: findAllByRequester(anAddress, lights.values()))) {
|
||||
DeviceResponse deviceResponse = null;
|
||||
if(!light.isInactive()) {
|
||||
if (!light.isInactive()) {
|
||||
if (light.containsType(DeviceMapTypes.HUE_DEVICE[DeviceMapTypes.typeIndex])) {
|
||||
CallItem[] callItems = null;
|
||||
try {
|
||||
if(light.getOnUrl() != null)
|
||||
if (light.getOnUrl() != null)
|
||||
callItems = aGsonBuilder.fromJson(light.getOnUrl(), CallItem[].class);
|
||||
} catch(JsonSyntaxException e) {
|
||||
log.warn("Could not decode Json for url items to get Hue state for device: " + light.getName());
|
||||
} catch (JsonSyntaxException e) {
|
||||
log.warn("Could not decode Json for url items to get Hue state for device: {}",
|
||||
light.getName());
|
||||
callItems = null;
|
||||
}
|
||||
|
||||
for (int i = 0; callItems != null && i < callItems.length; i++) {
|
||||
if((callItems[i].getType() != null && callItems[i].getType().equals(DeviceMapTypes.HUE_DEVICE[DeviceMapTypes.typeIndex])) ||
|
||||
(callItems[i].getItem() != null && callItems[i].getItem().getAsString() != null && callItems[i].getItem().getAsString().contains("hueName"))) {
|
||||
if ((callItems[i].getType() != null
|
||||
&& callItems[i].getType().equals(DeviceMapTypes.HUE_DEVICE[DeviceMapTypes.typeIndex]))
|
||||
|| (callItems[i].getItem() != null && callItems[i].getItem().getAsString() != null
|
||||
&& callItems[i].getItem().getAsString().contains("hueName"))) {
|
||||
deviceResponse = myHueHome.getHueDeviceInfo(callItems[i], light);
|
||||
i = callItems.length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (deviceResponse == null) {
|
||||
deviceResponse = DeviceResponse.createResponse(light);
|
||||
}
|
||||
deviceResponseMap.put(light.getId(), deviceResponse);
|
||||
deviceResponseMap.put(light.getId(), deviceResponse);
|
||||
}
|
||||
}
|
||||
return (deviceResponseMap.size() == 0) ? null : deviceResponseMap;
|
||||
}
|
||||
|
||||
public DeviceDescriptor findOne(String id) {
|
||||
return devices.get(id);
|
||||
}
|
||||
|
||||
return devices.get(id);
|
||||
}
|
||||
|
||||
private void put(String id, DeviceDescriptor aDescriptor) {
|
||||
devices.put(id, aDescriptor);
|
||||
}
|
||||
|
||||
devices.put(id, aDescriptor);
|
||||
}
|
||||
|
||||
public void save(DeviceDescriptor[] descriptors) {
|
||||
String theNames = "";
|
||||
for(int i = 0; i < descriptors.length; i++) {
|
||||
if(descriptors[i].getId() != null && descriptors[i].getId().length() > 0)
|
||||
devices.remove(descriptors[i].getId());
|
||||
else {
|
||||
nextId++;
|
||||
descriptors[i].setId(String.valueOf(nextId));
|
||||
}
|
||||
if(descriptors[i].getUniqueid() == null || descriptors[i].getUniqueid().length() == 0) {
|
||||
BigInteger bigInt = BigInteger.valueOf(Integer.decode(descriptors[i].getId()));
|
||||
byte[] theBytes = bigInt.toByteArray();
|
||||
String hexValue = DatatypeConverter.printHexBinary(theBytes);
|
||||
for (int i = 0; i < descriptors.length; i++) {
|
||||
if (descriptors[i].getId() != null && descriptors[i].getId().length() > 0)
|
||||
devices.remove(descriptors[i].getId());
|
||||
else {
|
||||
descriptors[i].setId(String.valueOf(nextId));
|
||||
nextId++;
|
||||
}
|
||||
if (descriptors[i].getUniqueid() == null || descriptors[i].getUniqueid().length() == 0) {
|
||||
String hexValue = HexLibrary.encodeUsingBigIntegerToString(descriptors[i].getId());
|
||||
|
||||
descriptors[i].setUniqueid("00:17:88:5E:D3:" + hexValue + "-" + hexValue);
|
||||
}
|
||||
put(descriptors[i].getId(), descriptors[i]);
|
||||
theNames = theNames + " " + descriptors[i].getName() + ", ";
|
||||
descriptors[i].setUniqueid("00:17:88:5E:D3:" + hexValue + "-" + hexValue);
|
||||
}
|
||||
put(descriptors[i].getId(), descriptors[i]);
|
||||
theNames = theNames + " " + descriptors[i].getName() + ", ";
|
||||
}
|
||||
String jsonValue = gson.toJson(findAll());
|
||||
repositoryWriter(jsonValue, repositoryPath);
|
||||
log.debug("Save device(s): " + theNames);
|
||||
}
|
||||
|
||||
String jsonValue = gson.toJson(findAll());
|
||||
repositoryWriter(jsonValue, repositoryPath);
|
||||
log.debug("Save device(s): {}", theNames);
|
||||
}
|
||||
|
||||
public void renumber() {
|
||||
List<DeviceDescriptor> list = new ArrayList<DeviceDescriptor>(devices.values());
|
||||
Iterator<DeviceDescriptor> deviceIterator = list.iterator();
|
||||
Map<String, DeviceDescriptor> newdevices = new HashMap<String, DeviceDescriptor>();;
|
||||
nextId = 0;
|
||||
log.debug("Renumber devices.");
|
||||
while(deviceIterator.hasNext()) {
|
||||
nextId++;
|
||||
DeviceDescriptor theDevice = deviceIterator.next();
|
||||
theDevice.setId(String.valueOf(nextId));
|
||||
BigInteger bigInt = BigInteger.valueOf(nextId);
|
||||
byte[] theBytes = bigInt.toByteArray();
|
||||
String hexValue = DatatypeConverter.printHexBinary(theBytes);
|
||||
|
||||
theDevice.setUniqueid("00:17:88:5E:D3:" + hexValue + "-" + hexValue);
|
||||
newdevices.put(theDevice.getId(), theDevice);
|
||||
}
|
||||
devices = newdevices;
|
||||
String jsonValue = gson.toJson(findAll());
|
||||
repositoryWriter(jsonValue, repositoryPath);
|
||||
}
|
||||
|
||||
public String delete(DeviceDescriptor aDescriptor) {
|
||||
if (aDescriptor != null) {
|
||||
devices.remove(aDescriptor.getId());
|
||||
JsonTransformer aRenderer = new JsonTransformer();
|
||||
String jsonValue = aRenderer.render(findAll());
|
||||
repositoryWriter(jsonValue, repositoryPath);
|
||||
return "Device with id '" + aDescriptor.getId() + "' deleted";
|
||||
} else {
|
||||
return "Device not found";
|
||||
}
|
||||
Map<String, DeviceDescriptor> newdevices = new HashMap<String, DeviceDescriptor>();
|
||||
|
||||
nextId = seedId;
|
||||
String hexValue;
|
||||
Integer newValue;
|
||||
DeviceDescriptor theDevice;
|
||||
log.debug("Renumber devices with seed: {}", seedId);
|
||||
while (deviceIterator.hasNext()) {
|
||||
theDevice = deviceIterator.next();
|
||||
if (!theDevice.isLockDeviceId()) {
|
||||
theDevice.setId(String.valueOf(nextId));
|
||||
newValue = nextId % 256;
|
||||
if (newValue <= 0)
|
||||
newValue = 1;
|
||||
else if (newValue > 255)
|
||||
newValue = 255;
|
||||
hexValue = HexLibrary.encodeUsingBigIntegerToString(newValue.toString());
|
||||
|
||||
theDevice.setUniqueid("00:17:88:5E:D3:" + hexValue + "-" + hexValue);
|
||||
nextId++;
|
||||
}
|
||||
newdevices.put(theDevice.getId(), theDevice);
|
||||
}
|
||||
devices = newdevices;
|
||||
String jsonValue = gson.toJson(findAll());
|
||||
repositoryWriter(jsonValue, repositoryPath);
|
||||
}
|
||||
|
||||
public String delete(DeviceDescriptor aDescriptor) {
|
||||
if (aDescriptor != null) {
|
||||
devices.remove(aDescriptor.getId());
|
||||
JsonTransformer aRenderer = new JsonTransformer();
|
||||
String jsonValue = aRenderer.render(findAll());
|
||||
repositoryWriter(jsonValue, repositoryPath);
|
||||
return "Device with id '" + aDescriptor.getId() + "' deleted";
|
||||
} else {
|
||||
return "Device not found";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void repositoryWriter(String content, Path filePath) {
|
||||
if(Files.exists(filePath) && !Files.isWritable(filePath)){
|
||||
log.error("Error file is not writable: " + filePath);
|
||||
if (Files.exists(filePath) && !Files.isWritable(filePath)) {
|
||||
log.error("Error file is not writable: {}", filePath);
|
||||
return;
|
||||
}
|
||||
|
||||
if(Files.notExists(filePath.getParent())) {
|
||||
|
||||
if (Files.notExists(filePath.getParent())) {
|
||||
try {
|
||||
Files.createDirectories(filePath.getParent());
|
||||
} catch (IOException e) {
|
||||
log.error("Error creating the directory: " + filePath + " message: " + e.getMessage(), e);
|
||||
log.error("Error creating the directory: {} message: {}", filePath, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
Path target = null;
|
||||
if(Files.exists(filePath)) {
|
||||
if (Files.exists(filePath)) {
|
||||
target = FileSystems.getDefault().getPath(filePath.getParent().toString(), "device.db.old");
|
||||
Files.move(filePath, target);
|
||||
}
|
||||
Files.write(filePath, content.getBytes(), StandardOpenOption.CREATE);
|
||||
if(target != null)
|
||||
if (target != null)
|
||||
Files.delete(target);
|
||||
} catch (IOException e) {
|
||||
log.error("Error writing the file: " + filePath + " message: " + e.getMessage(), e);
|
||||
log.error("Error writing the file: {} message: {}", filePath, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private String repositoryReader(Path filePath) {
|
||||
|
||||
String content = null;
|
||||
if(Files.notExists(filePath) || !Files.isReadable(filePath)){
|
||||
log.warn("Error reading the file: " + filePath + " - Does not exist or is not readable. continuing...");
|
||||
if (Files.notExists(filePath) || !Files.isReadable(filePath)) {
|
||||
log.warn("Error reading the file: {} - Does not exist or is not readable. continuing...", filePath);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
content = new String(Files.readAllBytes(filePath));
|
||||
} catch (IOException e) {
|
||||
log.error("Error reading the file: " + filePath + " message: " + e.getMessage(), e);
|
||||
log.error("Error reading the file: {} message: {}", filePath, e.getMessage(), e);
|
||||
}
|
||||
|
||||
|
||||
return content;
|
||||
}
|
||||
}
|
||||
@@ -44,13 +44,15 @@ public class DeviceResource {
|
||||
private BridgeSettings bridgeSettings;
|
||||
private Gson aGsonHandler;
|
||||
private static final Set<String> supportedVerbs = new HashSet<>(Arrays.asList("get", "put", "post"));
|
||||
private String errorMessage;
|
||||
|
||||
public DeviceResource(BridgeSettings theSettings, HomeManager aHomeManager) {
|
||||
bridgeSettings = theSettings;
|
||||
this.deviceRepository = new DeviceRepository(bridgeSettings.getBridgeSettingsDescriptor().getUpnpDeviceDb());
|
||||
this.deviceRepository = new DeviceRepository(bridgeSettings.getBridgeSettingsDescriptor().getUpnpDeviceDb(), bridgeSettings.getBridgeSettingsDescriptor().getSeedid());
|
||||
this.groupRepository = new GroupRepository(bridgeSettings.getBridgeSettingsDescriptor().getUpnpGroupDb());
|
||||
homeManager = aHomeManager;
|
||||
aGsonHandler = new GsonBuilder().create();
|
||||
errorMessage = null;
|
||||
setupEndpoints();
|
||||
}
|
||||
|
||||
@@ -83,7 +85,7 @@ public class DeviceResource {
|
||||
return "";
|
||||
});
|
||||
post(API_CONTEXT, "application/json", (request, response) -> {
|
||||
log.debug("Create a Device(s) - request body: " + request.body());
|
||||
log.debug("Create a Device(s) - request body: {}", request.body());
|
||||
DeviceDescriptor devices[];
|
||||
if(request.body().substring(0,1).equalsIgnoreCase("[") == true) {
|
||||
devices = new Gson().fromJson(request.body(), DeviceDescriptor[].class);
|
||||
@@ -93,13 +95,12 @@ public class DeviceResource {
|
||||
}
|
||||
@SuppressWarnings("unused")
|
||||
CallItem[] callItems = null;
|
||||
String errorMessage = null;
|
||||
for(int i = 0; i < devices.length; i++) {
|
||||
if(devices[i].getContentBody() != null ) {
|
||||
if (devices[i].getContentType() == null || devices[i].getHttpVerb() == null || !supportedVerbs.contains(devices[i].getHttpVerb().toLowerCase())) {
|
||||
response.status(HttpStatus.SC_BAD_REQUEST);
|
||||
errorMessage = "Bad http verb in create device(s) for name: " + devices[i].getName() + " with verb: " + devices[i].getHttpVerb();
|
||||
log.debug(errorMessage);
|
||||
log.warn(errorMessage);
|
||||
return new ErrorMessage(errorMessage);
|
||||
}
|
||||
}
|
||||
@@ -109,7 +110,7 @@ public class DeviceResource {
|
||||
} catch(JsonSyntaxException e) {
|
||||
response.status(HttpStatus.SC_BAD_REQUEST);
|
||||
errorMessage = "Bad on URL JSON in create device(s) for name: " + devices[i].getName() + " with on URL: " + devices[i].getOnUrl();
|
||||
log.debug(errorMessage);
|
||||
log.warn(errorMessage);
|
||||
return new ErrorMessage(errorMessage);
|
||||
}
|
||||
try {
|
||||
@@ -118,7 +119,7 @@ public class DeviceResource {
|
||||
} catch(JsonSyntaxException e) {
|
||||
response.status(HttpStatus.SC_BAD_REQUEST);
|
||||
errorMessage = "Bad dim URL JSON in create device(s) for name: " + devices[i].getName() + " with dim URL: " + devices[i].getDimUrl();
|
||||
log.debug(errorMessage);
|
||||
log.warn(errorMessage);
|
||||
return new ErrorMessage(errorMessage);
|
||||
}
|
||||
try {
|
||||
@@ -127,7 +128,7 @@ public class DeviceResource {
|
||||
} catch(JsonSyntaxException e) {
|
||||
response.status(HttpStatus.SC_BAD_REQUEST);
|
||||
errorMessage = "Bad off URL JSON in create device(s) for name: " + devices[i].getName() + " with off URL: " + devices[i].getOffUrl();
|
||||
log.debug(errorMessage);
|
||||
log.warn(errorMessage);
|
||||
return new ErrorMessage(errorMessage);
|
||||
}
|
||||
try {
|
||||
@@ -136,13 +137,13 @@ public class DeviceResource {
|
||||
} catch(JsonSyntaxException e) {
|
||||
response.status(HttpStatus.SC_BAD_REQUEST);
|
||||
errorMessage = "Bad color URL JSON in create device(s) for name: " + devices[i].getName() + " with color URL: " + devices[i].getColorUrl();
|
||||
log.debug(errorMessage);
|
||||
log.warn(errorMessage);
|
||||
return new ErrorMessage(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
deviceRepository.save(devices);
|
||||
log.debug("Created a Device(s): " + request.body());
|
||||
log.debug("Created a Device(s): {}", request.body());
|
||||
|
||||
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
|
||||
response.status(HttpStatus.SC_CREATED);
|
||||
@@ -160,16 +161,17 @@ public class DeviceResource {
|
||||
return "";
|
||||
});
|
||||
put (API_CONTEXT + "/:id", "application/json", (request, response) -> {
|
||||
log.debug("Edit a Device - request body: " + request.body());
|
||||
log.debug("Edit a Device - request body: {}", request.body());
|
||||
DeviceDescriptor device = new Gson().fromJson(request.body(), DeviceDescriptor.class);
|
||||
if(deviceRepository.findOne(request.params(":id")) == null){
|
||||
log.debug("Could not save an edited device, Device Id not found: " + request.params(":id"));
|
||||
errorMessage = "Could not save an edited device, Device Id not found: " + request.params(":id");
|
||||
log.warn(errorMessage);
|
||||
response.status(HttpStatus.SC_BAD_REQUEST);
|
||||
return new ErrorMessage("Could not save an edited device, Device Id not found: " + request.params(":id") + " ");
|
||||
return new ErrorMessage(errorMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
log.debug("Saving an edited Device: " + device.getName());
|
||||
log.debug("Saving an edited Device: {}", device.getName());
|
||||
|
||||
if (device.getDeviceType() != null)
|
||||
device.setDeviceType(device.getDeviceType());
|
||||
@@ -187,17 +189,19 @@ public class DeviceResource {
|
||||
log.debug("Get all devices");
|
||||
JsonTransformer aRenderer = new JsonTransformer();
|
||||
String theStream = aRenderer.render(deviceList);
|
||||
log.debug("The Device List: " + theStream);
|
||||
log.debug("The Device List: {}", theStream);
|
||||
response.status(HttpStatus.SC_OK);
|
||||
return deviceList;
|
||||
}, new JsonTransformer());
|
||||
|
||||
get (API_CONTEXT + "/:id", "application/json", (request, response) -> {
|
||||
log.debug("Get a device");
|
||||
log.debug("Get a device: {}", request.params(":id"));
|
||||
DeviceDescriptor descriptor = deviceRepository.findOne(request.params(":id"));
|
||||
if(descriptor == null) {
|
||||
errorMessage = "Could not find, id: " + request.params(":id");
|
||||
log.warn(errorMessage);
|
||||
response.status(HttpStatus.SC_NOT_FOUND);
|
||||
return new ErrorMessage("Could not find, id: " + request.params(":id") + " ");
|
||||
return new ErrorMessage(errorMessage);
|
||||
}
|
||||
else
|
||||
response.status(HttpStatus.SC_OK);
|
||||
@@ -206,11 +210,13 @@ public class DeviceResource {
|
||||
|
||||
delete (API_CONTEXT + "/:id", "application/json", (request, response) -> {
|
||||
String anId = request.params(":id");
|
||||
log.debug("Delete a device: " + anId);
|
||||
log.debug("Delete a device: {}", anId);
|
||||
DeviceDescriptor deleted = deviceRepository.findOne(anId);
|
||||
if(deleted == null) {
|
||||
errorMessage = "Could not delete, id: " + anId + " not found. ";
|
||||
log.warn(errorMessage);
|
||||
response.status(HttpStatus.SC_NOT_FOUND);
|
||||
return new ErrorMessage("Could not delete, id: " + anId + " not found. ");
|
||||
return new ErrorMessage(errorMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -315,11 +321,49 @@ public class DeviceResource {
|
||||
return homeManager.findResource(DeviceMapTypes.SOMFY_DEVICE[DeviceMapTypes.typeIndex]).getItems(DeviceMapTypes.SOMFY_DEVICE[DeviceMapTypes.typeIndex]);
|
||||
}, new JsonTransformer());
|
||||
|
||||
get (API_CONTEXT + "/openhab/devices", "application/json", (request, response) -> {
|
||||
log.debug("Get OpenHAB devices");
|
||||
response.status(HttpStatus.SC_OK);
|
||||
return homeManager.findResource(DeviceMapTypes.OPENHAB_DEVICE[DeviceMapTypes.typeIndex]).getItems(DeviceMapTypes.OPENHAB_DEVICE[DeviceMapTypes.typeIndex]);
|
||||
}, new JsonTransformer());
|
||||
|
||||
get (API_CONTEXT + "/fhem/devices", "application/json", (request, response) -> {
|
||||
log.debug("Get FHEM devices");
|
||||
response.status(HttpStatus.SC_OK);
|
||||
return homeManager.findResource(DeviceMapTypes.FHEM_DEVICE[DeviceMapTypes.typeIndex]).getItems(DeviceMapTypes.FHEM_DEVICE[DeviceMapTypes.typeIndex]);
|
||||
}, new JsonTransformer());
|
||||
|
||||
get (API_CONTEXT + "/broadlink/devices", "application/json", (request, response) -> {
|
||||
log.debug("Get Broadlink devices");
|
||||
response.status(HttpStatus.SC_OK);
|
||||
return homeManager.findResource(DeviceMapTypes.BROADLINK_DEVICE[DeviceMapTypes.typeIndex]).getItems(DeviceMapTypes.BROADLINK_DEVICE[DeviceMapTypes.typeIndex]);
|
||||
}, new JsonTransformer());
|
||||
|
||||
get (API_CONTEXT + "/moziot/devices", "application/json", (request, response) -> {
|
||||
log.debug("Get Mozilla IOT devices");
|
||||
response.status(HttpStatus.SC_OK);
|
||||
return homeManager.findResource(DeviceMapTypes.MOZIOT_DEVICE[DeviceMapTypes.typeIndex]).getItems(DeviceMapTypes.MOZIOT_DEVICE[DeviceMapTypes.typeIndex]);
|
||||
}, new JsonTransformer());
|
||||
|
||||
get (API_CONTEXT + "/homegenie/devices", "application/json", (request, response) -> {
|
||||
log.debug("Get HomeGenie devices");
|
||||
response.status(HttpStatus.SC_OK);
|
||||
return homeManager.findResource(DeviceMapTypes.HOMEGENIE_DEVICE[DeviceMapTypes.typeIndex]).getItems(DeviceMapTypes.HOMEGENIE_DEVICE[DeviceMapTypes.typeIndex]);
|
||||
}, new JsonTransformer());
|
||||
|
||||
get (API_CONTEXT + "/map/types", "application/json", (request, response) -> {
|
||||
log.debug("Get map types");
|
||||
return new DeviceMapTypes().getDeviceMapTypes();
|
||||
}, new JsonTransformer());
|
||||
|
||||
get (API_CONTEXT + "/refresh/:typeIndex", "application/json", (request, response) -> {
|
||||
String typeIndex = request.params(":typeIndex");
|
||||
log.debug("Refresh Home: {}", typeIndex);
|
||||
response.status(HttpStatus.SC_OK);
|
||||
homeManager.findResource(typeIndex).refresh();
|
||||
return null;
|
||||
}, new JsonTransformer());
|
||||
|
||||
// http://ip_address:port/api/devices/exec/renumber CORS request
|
||||
options(API_CONTEXT + "/exec/renumber", "application/json", (request, response) -> {
|
||||
response.status(HttpStatus.SC_OK);
|
||||
@@ -336,11 +380,46 @@ public class DeviceResource {
|
||||
}, new JsonTransformer());
|
||||
|
||||
get (API_CONTEXT + "/backup/available", "application/json", (request, response) -> {
|
||||
log.debug("Get backup filenames");
|
||||
log.debug("Get backup filenames.");
|
||||
response.status(HttpStatus.SC_OK);
|
||||
return deviceRepository.getBackups();
|
||||
}, new JsonTransformer());
|
||||
|
||||
// http://ip_address:port/api/devices/backup/download CORS request
|
||||
options(API_CONTEXT + "/backup/download", "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 (API_CONTEXT + "/backup/download", "application/json", (request, response) -> {
|
||||
log.debug("Create download: {}", request.body());
|
||||
BackupFilename aFilename = new Gson().fromJson(request.body(), BackupFilename.class);
|
||||
String backupContent = deviceRepository.downloadBackup(aFilename.getFilename());
|
||||
return backupContent;
|
||||
}, new JsonTransformer());
|
||||
|
||||
// http://ip_address:port/api/devices/backup/upload CORS request
|
||||
options(API_CONTEXT + "/backup/upload/:filename", "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 (API_CONTEXT + "/backup/upload/:filename", "application/json", (request, response) -> {
|
||||
log.debug("Create upload: {} - {}", request.params(":filename"), request.body());
|
||||
String theSuccess = deviceRepository.uploadBackup(request.params(":filename"), request.body());
|
||||
if(theSuccess.contains("Error:"))
|
||||
response.status(HttpStatus.SC_METHOD_FAILURE);
|
||||
else
|
||||
response.status(HttpStatus.SC_OK);
|
||||
return theSuccess;
|
||||
}, new JsonTransformer());
|
||||
|
||||
// http://ip_address:port/api/devices/backup/create CORS request
|
||||
options(API_CONTEXT + "/backup/create", "application/json", (request, response) -> {
|
||||
response.status(HttpStatus.SC_OK);
|
||||
@@ -351,7 +430,7 @@ public class DeviceResource {
|
||||
return "";
|
||||
});
|
||||
put (API_CONTEXT + "/backup/create", "application/json", (request, response) -> {
|
||||
log.debug("Create backup: " + request.body());
|
||||
log.debug("Create backup: {}", request.body());
|
||||
BackupFilename aFilename = new Gson().fromJson(request.body(), BackupFilename.class);
|
||||
BackupFilename returnFilename = new BackupFilename();
|
||||
returnFilename.setFilename(deviceRepository.backup(aFilename.getFilename()));
|
||||
@@ -368,7 +447,7 @@ public class DeviceResource {
|
||||
return "";
|
||||
});
|
||||
post (API_CONTEXT + "/backup/delete", "application/json", (request, response) -> {
|
||||
log.debug("Delete backup: " + request.body());
|
||||
log.debug("Delete backup: {}", request.body());
|
||||
BackupFilename aFilename = new Gson().fromJson(request.body(), BackupFilename.class);
|
||||
if(aFilename != null)
|
||||
deviceRepository.deleteBackup(aFilename.getFilename());
|
||||
@@ -387,7 +466,7 @@ public class DeviceResource {
|
||||
return "";
|
||||
});
|
||||
post (API_CONTEXT + "/backup/restore", "application/json", (request, response) -> {
|
||||
log.debug("Restore backup: " + request.body());
|
||||
log.debug("Restore backup: {}", request.body());
|
||||
BackupFilename aFilename = new Gson().fromJson(request.body(), BackupFilename.class);
|
||||
if(aFilename != null) {
|
||||
deviceRepository.restoreBackup(aFilename.getFilename());
|
||||
|
||||
@@ -2,4 +2,5 @@ package com.bwssystems.HABridge.devicemanagmeent;
|
||||
|
||||
public interface ResourceHandler {
|
||||
public Object getItems(String type);
|
||||
public void refresh();
|
||||
}
|
||||
|
||||
@@ -52,11 +52,22 @@ public class BrightnessDecode {
|
||||
boolean notDone = true;
|
||||
String replaceValue = null;
|
||||
String replaceTarget = null;
|
||||
int percentBrightness = (int) Math.round(intensity / 255.0 * 100);
|
||||
float decimalBrightness = (float) (intensity / 255.0);
|
||||
int percentBrightness = 0;
|
||||
float decimalBrightness = (float) 0.0;
|
||||
Map<String, BigDecimal> variables = new HashMap<String, BigDecimal>();
|
||||
String mathDescriptor = null;
|
||||
|
||||
|
||||
if(intensity > 0) {
|
||||
decimalBrightness = (float) (intensity / 255.0);
|
||||
if(intensity > 0 && intensity < 5)
|
||||
percentBrightness = 1;
|
||||
else
|
||||
percentBrightness = (int) Math.round(intensity / 255.0 * 100);
|
||||
} else {
|
||||
decimalBrightness = (float) 0.0;
|
||||
percentBrightness = 0;
|
||||
}
|
||||
|
||||
while(notDone) {
|
||||
notDone = false;
|
||||
if (request.contains(INTENSITY_BYTE)) {
|
||||
@@ -111,11 +122,7 @@ public class BrightnessDecode {
|
||||
|
||||
Integer endResult = calculateMath(variables, mathDescriptor);
|
||||
if(endResult != null) {
|
||||
if (isHex) {
|
||||
replaceValue = convertToHex(endResult);
|
||||
} else {
|
||||
replaceValue = endResult.toString();
|
||||
}
|
||||
replaceValue = convertToHex(endResult);
|
||||
replaceTarget = INTENSITY_MATH + mathDescriptor + INTENSITY_MATH_CLOSE_HEX;
|
||||
notDone = true;
|
||||
}
|
||||
|
||||
@@ -19,4 +19,10 @@ public class ColorData {
|
||||
return mode;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
String formatString;
|
||||
|
||||
formatString = "Color Data mode: " + mode + ", data: " + data;
|
||||
return formatString;
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -20,93 +20,184 @@ public class ColorDecode {
|
||||
private static final String COLOR_GX = "${color.gx}";
|
||||
private static final String COLOR_BX = "${color.bx}";
|
||||
private static final String COLOR_RGBX = "${color.rgbx}";
|
||||
private static final String COLOR_HSL = "${color.hsl}";
|
||||
private static final Pattern COLOR_MILIGHT = Pattern.compile("\\$\\{color.milight\\:([01234])\\}");
|
||||
|
||||
public static List<Integer> convertHSLtoRGB(HueSatBri hsl) {
|
||||
List<Integer> rgb;
|
||||
float decimalBrightness = (float) 0.0;
|
||||
float var_1 = (float) 0.0;
|
||||
float var_2 = (float) 0.0;
|
||||
float h = (float) 0.0;
|
||||
float h2 = (float) 0.0;
|
||||
float s = (float) 0.0;
|
||||
double r = 0.0;
|
||||
double g = 0.0;
|
||||
double b = 0.0;
|
||||
|
||||
if(hsl.getBri() > 0)
|
||||
decimalBrightness = (float) (hsl.getBri() / 255.0);
|
||||
|
||||
if(hsl.getHue() > 0) {
|
||||
h = ((float)hsl.getHue() / (float)65535.0);
|
||||
h2 = h + (float)0.5;
|
||||
if(h2 > 1.0) {
|
||||
h2 = h2 - (float)1.0;
|
||||
}
|
||||
}
|
||||
if(hsl.getSat() > 0) {
|
||||
s = (float)(hsl.getSat() / 254.0);
|
||||
}
|
||||
|
||||
if (s == 0)
|
||||
{
|
||||
r = decimalBrightness * (float)255;
|
||||
g = decimalBrightness * (float)255;
|
||||
b = decimalBrightness * (float)255;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (decimalBrightness < 0.5)
|
||||
{
|
||||
var_2 = decimalBrightness * (1 + s);
|
||||
}
|
||||
else
|
||||
{
|
||||
var_2 = (decimalBrightness + s) - (s * decimalBrightness);
|
||||
};
|
||||
|
||||
var_1 = 2 * decimalBrightness - var_2;
|
||||
float onethird = (float)0.33333;
|
||||
float h2Plus = (h2 + onethird);
|
||||
float h2Minus = (h2 - onethird);
|
||||
log.debug("calculate HSL vars - var1: " + var_1 + ", var_2: " + var_2 + ", h2: " + h2 + ", h2 + 1/3: " + h2Plus + ", h2 - 1/3: " + h2Minus);
|
||||
r = 255 * hue_2_rgb(var_1, var_2, h2Plus);
|
||||
g = 255 * hue_2_rgb(var_1, var_2, h2);
|
||||
b = 255 * hue_2_rgb(var_1, var_2, h2Minus);
|
||||
};
|
||||
|
||||
rgb = new ArrayList<Integer>();
|
||||
rgb.add((int) Math.round(r));
|
||||
rgb.add((int) Math.round(g));
|
||||
rgb.add((int) Math.round(b));
|
||||
|
||||
log.debug("Color change with HSL: " + hsl + ". Resulting RGB Values: " + rgb.get(0) + " " + rgb.get(1) + " "
|
||||
+ rgb.get(2));
|
||||
return rgb;
|
||||
}
|
||||
|
||||
public static float hue_2_rgb(float v1, float v2, float vh) {
|
||||
log.debug("hue_2_rgb vh: " + vh);
|
||||
if (vh < 0.0)
|
||||
{
|
||||
vh = vh + (float)1;
|
||||
};
|
||||
|
||||
if (vh > 1.0)
|
||||
{
|
||||
vh = vh - (float)1;
|
||||
};
|
||||
|
||||
if (((float)6.0 * vh) < 1.0)
|
||||
{
|
||||
return (v1 + (v2 - v1) * (float)6.0 * vh);
|
||||
};
|
||||
|
||||
if (((float)2.0 * vh) < 1.0)
|
||||
{
|
||||
return (v2);
|
||||
};
|
||||
|
||||
if ((3.0 * vh) < 2.0)
|
||||
{
|
||||
return (v1 + (v2 - v1) * (((float)2.0 / (float)3.0 - vh) * (float)6.0));
|
||||
};
|
||||
|
||||
return (v1);
|
||||
}
|
||||
|
||||
public static List<Integer> convertCIEtoRGB(List<Double> xy, int brightness) {
|
||||
List<Integer> rgb;
|
||||
double x = xy.get(0); // the given x value
|
||||
double y = xy.get(1); // the given y value
|
||||
double z = 1.0 - x - y;
|
||||
double Y = (double)brightness/(double)254.00; // The given brightness value
|
||||
double Y = (double) brightness / (double) 254.00; // The given brightness value
|
||||
double X = (Y / y) * x;
|
||||
double Z = (Y / y) * z;
|
||||
|
||||
double r = X * 1.656492 - Y * 0.354851 - Z * 0.255038;
|
||||
double r = X * 1.656492 - Y * 0.354851 - Z * 0.255038;
|
||||
double g = -X * 0.707196 + Y * 1.655397 + Z * 0.036152;
|
||||
double b = X * 0.051713 - Y * 0.121364 + Z * 1.011530;
|
||||
double b = X * 0.051713 - Y * 0.121364 + Z * 1.011530;
|
||||
|
||||
if (r > b && r > g && r > 1.0) {
|
||||
|
||||
g = g / r;
|
||||
b = b / r;
|
||||
r = 1.0;
|
||||
}
|
||||
else if (g > b && g > r && g > 1.0) {
|
||||
} else if (g > b && g > r && g > 1.0) {
|
||||
|
||||
r = r / g;
|
||||
b = b / g;
|
||||
g = 1.0;
|
||||
}
|
||||
else if (b > r && b > g && b > 1.0) {
|
||||
} else if (b > r && b > g && b > 1.0) {
|
||||
|
||||
r = r / b;
|
||||
g = g / b;
|
||||
b = 1.0;
|
||||
}
|
||||
|
||||
|
||||
r = r <= 0.0031308 ? 12.92 * r : (1.0 + 0.055) * Math.pow(r, (1.0 / 2.4)) - 0.055;
|
||||
g = g <= 0.0031308 ? 12.92 * g : (1.0 + 0.055) * Math.pow(g, (1.0 / 2.4)) - 0.055;
|
||||
b = b <= 0.0031308 ? 12.92 * b : (1.0 + 0.055) * Math.pow(b, (1.0 / 2.4)) - 0.055;
|
||||
|
||||
if (r > b && r > g) {
|
||||
// red is biggest
|
||||
if (r > 1.0) {
|
||||
g = g / r;
|
||||
b = b / r;
|
||||
r = 1.0;
|
||||
}
|
||||
}
|
||||
else if (g > b && g > r) {
|
||||
// green is biggest
|
||||
if (g > 1.0) {
|
||||
r = r / g;
|
||||
b = b / g;
|
||||
g = 1.0;
|
||||
}
|
||||
}
|
||||
else if (b > r && b > g) {
|
||||
// blue is biggest
|
||||
if (b > 1.0) {
|
||||
r = r / b;
|
||||
g = g / b;
|
||||
b = 1.0;
|
||||
}
|
||||
}
|
||||
if(r < 0.0)
|
||||
r = 0;
|
||||
if(g < 0.0)
|
||||
g = 0;
|
||||
if(b < 0.0)
|
||||
b = 0;
|
||||
|
||||
rgb = new ArrayList<Integer>();
|
||||
rgb.add((int)Math.round(r * 255));
|
||||
rgb.add((int)Math.round(g * 255));
|
||||
rgb.add((int)Math.round(b * 255));
|
||||
log.debug("Color change with XY: " + x + " " + y + " Resulting RGB Values: " + rgb.get(0) + " " + rgb.get(1) + " " + rgb.get(2));
|
||||
if (r > b && r > g) {
|
||||
// red is biggest
|
||||
if (r > 1.0) {
|
||||
g = g / r;
|
||||
b = b / r;
|
||||
r = 1.0;
|
||||
}
|
||||
} else if (g > b && g > r) {
|
||||
// green is biggest
|
||||
if (g > 1.0) {
|
||||
r = r / g;
|
||||
b = b / g;
|
||||
g = 1.0;
|
||||
}
|
||||
} else if (b > r && b > g) {
|
||||
// blue is biggest
|
||||
if (b > 1.0) {
|
||||
r = r / b;
|
||||
g = g / b;
|
||||
b = 1.0;
|
||||
}
|
||||
}
|
||||
if (r < 0.0)
|
||||
r = 0;
|
||||
if (g < 0.0)
|
||||
g = 0;
|
||||
if (b < 0.0)
|
||||
b = 0;
|
||||
|
||||
rgb = new ArrayList<Integer>();
|
||||
rgb.add((int) Math.round(r * 255));
|
||||
rgb.add((int) Math.round(g * 255));
|
||||
rgb.add((int) Math.round(b * 255));
|
||||
log.debug("Color change with XY: " + x + " " + y + " Resulting RGB Values: " + rgb.get(0) + " " + rgb.get(1)
|
||||
+ " " + rgb.get(2));
|
||||
return rgb;
|
||||
}
|
||||
|
||||
// took that approximation from http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code/
|
||||
// took that approximation from
|
||||
// http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code/
|
||||
public static List<Integer> convertCTtoRGB(Integer ct) {
|
||||
double temperature = 1000000.0 / (double)ct;
|
||||
double temperature = 1000000.0 / (double) ct;
|
||||
temperature /= 100;
|
||||
double r,g,b;
|
||||
double r, g, b;
|
||||
if (temperature <= 66) {
|
||||
r = 255;
|
||||
g = temperature;
|
||||
g = 99.4708025861 * Math.log(g) - 161.1195681661;
|
||||
g = 99.4708025861 * Math.log(g) - 161.1195681661;
|
||||
} else {
|
||||
r = temperature - 60;
|
||||
r = 329.698727446 * (Math.pow(r, -0.1332047592));
|
||||
@@ -124,25 +215,26 @@ public class ColorDecode {
|
||||
b = 138.5177312231 * Math.log(b) - 305.0447927307;
|
||||
}
|
||||
}
|
||||
r = assureBounds(r);
|
||||
g = assureBounds(g);
|
||||
b = assureBounds(b);
|
||||
List<Integer> rgb = new ArrayList<Integer>();
|
||||
rgb.add((int)Math.round(r));
|
||||
rgb.add((int)Math.round(g));
|
||||
rgb.add((int)Math.round(b));
|
||||
log.debug("Color change with CT: " + ct + ". Resulting RGB Values: " + rgb.get(0) + " " + rgb.get(1) + " " + rgb.get(2));
|
||||
return rgb;
|
||||
r = assureBounds(r);
|
||||
g = assureBounds(g);
|
||||
b = assureBounds(b);
|
||||
List<Integer> rgb = new ArrayList<Integer>();
|
||||
rgb.add((int) Math.round(r));
|
||||
rgb.add((int) Math.round(g));
|
||||
rgb.add((int) Math.round(b));
|
||||
log.debug("Color change with CT: " + ct + ". Resulting RGB Values: " + rgb.get(0) + " " + rgb.get(1) + " "
|
||||
+ rgb.get(2));
|
||||
return rgb;
|
||||
}
|
||||
|
||||
private static double assureBounds(double value) {
|
||||
if (value < 0.0) {
|
||||
value = 0;
|
||||
}
|
||||
if (value > 255.0) {
|
||||
value = 255;
|
||||
}
|
||||
return value;
|
||||
value = 0;
|
||||
}
|
||||
if (value > 255.0) {
|
||||
value = 255;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -157,25 +249,30 @@ public class ColorDecode {
|
||||
ColorData.ColorMode colorMode = colorData.getColorMode();
|
||||
List<Integer> rgb = null;
|
||||
if (colorMode == ColorData.ColorMode.XY) {
|
||||
rgb = convertCIEtoRGB((List<Double>)colorData.getData(), setIntensity);
|
||||
rgb = convertCIEtoRGB((List<Double>) colorData.getData(), setIntensity);
|
||||
} else if (colorMode == ColorData.ColorMode.CT) {
|
||||
rgb = convertCTtoRGB((Integer)colorData.getData());
|
||||
rgb = convertCTtoRGB((Integer) colorData.getData());
|
||||
} else if (colorMode == ColorData.ColorMode.HS) {
|
||||
rgb = convertHSLtoRGB((HueSatBri) colorData.getData());
|
||||
}
|
||||
|
||||
while(notDone) {
|
||||
|
||||
while (notDone) {
|
||||
notDone = false;
|
||||
if (request.contains(COLOR_R)) {
|
||||
request = request.replace(COLOR_R, isHex ? String.format("%02X", rgb.get(0)) : String.valueOf(rgb.get(0)));
|
||||
request = request.replace(COLOR_R,
|
||||
isHex ? String.format("%02X", rgb.get(0)) : String.valueOf(rgb.get(0)));
|
||||
notDone = true;
|
||||
}
|
||||
|
||||
if (request.contains(COLOR_G)) {
|
||||
request = request.replace(COLOR_G, isHex ? String.format("%02X", rgb.get(1)) : String.valueOf(rgb.get(1)));
|
||||
request = request.replace(COLOR_G,
|
||||
isHex ? String.format("%02X", rgb.get(1)) : String.valueOf(rgb.get(1)));
|
||||
notDone = true;
|
||||
}
|
||||
|
||||
if (request.contains(COLOR_B)) {
|
||||
request = request.replace(COLOR_B, isHex ? String.format("%02X", rgb.get(2)) : String.valueOf(rgb.get(2)));
|
||||
request = request.replace(COLOR_B,
|
||||
isHex ? String.format("%02X", rgb.get(2)) : String.valueOf(rgb.get(2)));
|
||||
notDone = true;
|
||||
}
|
||||
|
||||
@@ -195,64 +292,93 @@ public class ColorDecode {
|
||||
}
|
||||
|
||||
if (request.contains(COLOR_RGBX)) {
|
||||
request = request.replace(COLOR_RGBX, String.format("%02X%02X%02X", rgb.get(0), rgb.get(1), rgb.get(2)));
|
||||
request = request.replace(COLOR_RGBX,
|
||||
String.format("%02X%02X%02X", rgb.get(0), rgb.get(1), rgb.get(2)));
|
||||
notDone = true;
|
||||
}
|
||||
|
||||
|
||||
if (request.contains(COLOR_HSL)) {
|
||||
float[] hsb = new float[3];
|
||||
Color.RGBtoHSB(rgb.get(0), rgb.get(1), rgb.get(2), hsb);
|
||||
float hue = hsb[0] * (float) 360.0;
|
||||
float sat = hsb[1] * (float) 100.0;
|
||||
float bright = hsb[2] * (float) 100.0;
|
||||
request = request.replace(COLOR_HSL, String.format("%f,%f,%f", hue, sat, bright));
|
||||
notDone = true;
|
||||
}
|
||||
|
||||
Matcher m = COLOR_MILIGHT.matcher(request);
|
||||
while (m.find()) {
|
||||
int group = Integer.parseInt(m.group(1));
|
||||
request = m.replaceFirst(getMilightV5FromRgb(rgb, group));
|
||||
m.reset(request);
|
||||
int group = Integer.parseInt(m.group(1));
|
||||
request = m.replaceFirst(getMilightV5FromRgb(rgb, group));
|
||||
m.reset(request);
|
||||
}
|
||||
|
||||
|
||||
log.debug("Request <<" + request + ">>, not done: " + notDone);
|
||||
}
|
||||
return request;
|
||||
}
|
||||
|
||||
private static String getMilightV5FromRgb(List<Integer> rgb, int group) {
|
||||
double r = (double)rgb.get(0);
|
||||
double g = (double)rgb.get(1);
|
||||
double b = (double)rgb.get(2);
|
||||
if (r > 245 && g > 245 && b > 245) { // it's white
|
||||
String retVal = "";
|
||||
if (group == 0) {
|
||||
retVal += "C2";
|
||||
} else if (group == 1) {
|
||||
retVal += "C5";
|
||||
} else if (group == 2) {
|
||||
retVal += "C7";
|
||||
} else if (group == 3) {
|
||||
retVal += "C9";
|
||||
} else if (group == 4) {
|
||||
retVal += "CB";
|
||||
}
|
||||
log.debug("Convert RGB to Milight. Result: WHITE. RGB Values: " + rgb.get(0) + " " + rgb.get(1) + " " + rgb.get(2));
|
||||
return retVal + "0055";
|
||||
} else { // normal color
|
||||
r /= (double)0xFF;
|
||||
g /= (double)0xFF;
|
||||
b /= (double)0xFF;
|
||||
double max = Math.max(Math.max(r, g), b), min = Math.min(Math.min(r, g), b);
|
||||
double h = 0;
|
||||
double d = max - min;
|
||||
double r = (double) rgb.get(0);
|
||||
double g = (double) rgb.get(1);
|
||||
double b = (double) rgb.get(2);
|
||||
if (r > 245 && g > 245 && b > 245) { // it's white
|
||||
String retVal = "";
|
||||
if (group == 0) {
|
||||
retVal += "C2";
|
||||
} else if (group == 1) {
|
||||
retVal += "C5";
|
||||
} else if (group == 2) {
|
||||
retVal += "C7";
|
||||
} else if (group == 3) {
|
||||
retVal += "C9";
|
||||
} else if (group == 4) {
|
||||
retVal += "CB";
|
||||
}
|
||||
log.debug("Convert RGB to Milight. Result: WHITE. RGB Values: " + rgb.get(0) + " " + rgb.get(1) + " "
|
||||
+ rgb.get(2));
|
||||
return retVal + "0055";
|
||||
} else { // normal color
|
||||
r /= (double) 0xFF;
|
||||
g /= (double) 0xFF;
|
||||
b /= (double) 0xFF;
|
||||
double max = Math.max(Math.max(r, g), b), min = Math.min(Math.min(r, g), b);
|
||||
double h = 0;
|
||||
double d = max - min;
|
||||
|
||||
if (max == min) {
|
||||
h = 0;
|
||||
} else {
|
||||
if (max == r) {
|
||||
h = ((g - b) / d + (g < b ? 6 : 0));
|
||||
} else if (max == g) {
|
||||
h = ((b - r) / d + 2);
|
||||
} else if (max == b){
|
||||
h = ((r - g) / d + 4);
|
||||
}
|
||||
h = Math.round(h * 60);
|
||||
}
|
||||
int milight = (int)((256 + 176 - Math.floor(h / 360.0 * 255.0)) % 256);
|
||||
log.debug("Convert RGB to Milight. Result: " + milight + " RGB Values: " + rgb.get(0) + " " + rgb.get(1) + " " + rgb.get(2));
|
||||
return "40" + String.format("%02X", milight) + "55";
|
||||
}
|
||||
if (max == min) {
|
||||
h = 0;
|
||||
} else {
|
||||
if (max == r) {
|
||||
h = ((g - b) / d + (g < b ? 6 : 0));
|
||||
} else if (max == g) {
|
||||
h = ((b - r) / d + 2);
|
||||
} else if (max == b) {
|
||||
h = ((r - g) / d + 4);
|
||||
}
|
||||
h = Math.round(h * 60);
|
||||
}
|
||||
int milight = (int) ((256 + 176 - Math.floor(h / 360.0 * 255.0)) % 256);
|
||||
log.debug("Convert RGB to Milight. Result: " + milight + " RGB Values: " + rgb.get(0) + " " + rgb.get(1)
|
||||
+ " " + rgb.get(2));
|
||||
return "40" + String.format("%02X", milight) + "55";
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static int getIntRGB(ColorData colorData, int setIntensity) {
|
||||
ColorData.ColorMode colorMode = colorData.getColorMode();
|
||||
List<Integer> rgb = null;
|
||||
if (colorMode == ColorData.ColorMode.XY) {
|
||||
rgb = convertCIEtoRGB((List<Double>) colorData.getData(), setIntensity);
|
||||
} else if (colorMode == ColorData.ColorMode.CT) {
|
||||
rgb = convertCTtoRGB((Integer) colorData.getData());
|
||||
}
|
||||
|
||||
int rgbIntVal = Integer.parseInt(String.format("%02X%02X%02X", rgb.get(0), rgb.get(1), rgb.get(2)), 16);
|
||||
log.debug("Convert RGB to int. Result: " + rgbIntVal + " RGB Values: " + rgb.get(0) + " " + rgb.get(1) + " "
|
||||
+ rgb.get(2));
|
||||
return rgbIntVal;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
38
src/main/java/com/bwssystems/HABridge/hue/HueSatBri.java
Normal file
38
src/main/java/com/bwssystems/HABridge/hue/HueSatBri.java
Normal file
@@ -0,0 +1,38 @@
|
||||
package com.bwssystems.HABridge.hue;
|
||||
|
||||
public class HueSatBri {
|
||||
int hue;
|
||||
int sat;
|
||||
int 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 int getBri() {
|
||||
return bri;
|
||||
}
|
||||
|
||||
public void setBri(int bri) {
|
||||
this.bri = bri;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
String formatString = new String();
|
||||
|
||||
formatString = "Hue: " + Integer.toString(hue) + ", Sat: " + Integer.toString(sat) + ", Bri: " + Integer.toString(bri);
|
||||
return formatString;
|
||||
}
|
||||
}
|
||||
@@ -119,13 +119,13 @@ public class NestHome implements com.bwssystems.HABridge.Home {
|
||||
log.warn("Should not get here, no Nest available");
|
||||
responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
|
||||
+ "\",\"description\": \"Should not get here, no Nest available\", \"parameter\": \"/lights/"
|
||||
+ lightId + "state\"}}]";
|
||||
+ lightId + "/state\"}}]";
|
||||
} else if (anItem.getType() != null && anItem.getType().trim().equalsIgnoreCase(DeviceMapTypes.NEST_HOMEAWAY[DeviceMapTypes.typeIndex])) {
|
||||
NestInstruction homeAway = null;
|
||||
if(anItem.getItem().isJsonObject())
|
||||
homeAway = aGsonHandler.fromJson(anItem.getItem(), NestInstruction.class);
|
||||
else
|
||||
homeAway = aGsonHandler.fromJson(anItem.getItem().getAsString(), NestInstruction.class);
|
||||
homeAway = aGsonHandler.fromJson(anItem.getItem().getAsString().replaceAll("^\"|\"$", ""), NestInstruction.class);
|
||||
theNest.getHome(homeAway.getName()).setAway(homeAway.getAway());
|
||||
} else if (anItem.getType() != null && anItem.getType().trim().equalsIgnoreCase(DeviceMapTypes.NEST_THERMO_SET[DeviceMapTypes.typeIndex])) {
|
||||
NestInstruction thermoSetting = null;
|
||||
@@ -167,7 +167,7 @@ public class NestHome implements com.bwssystems.HABridge.Home {
|
||||
log.warn("no valid Nest control info: " + thermoSetting.getControl());
|
||||
responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
|
||||
+ "\",\"description\": \"no valid Nest control info\", \"parameter\": \"/lights/"
|
||||
+ lightId + "state\"}}]";
|
||||
+ lightId + "/state\"}}]";
|
||||
}
|
||||
}
|
||||
return responseString;
|
||||
@@ -197,5 +197,10 @@ public class NestHome implements com.bwssystems.HABridge.Home {
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh() {
|
||||
// noop
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
package com.bwssystems.HABridge.plugins.broadlink;
|
||||
|
||||
public class BroadlinkEntry {
|
||||
private String name;
|
||||
private String id;
|
||||
private String ipAddr;
|
||||
private String macAddr;
|
||||
private String command;
|
||||
private String data;
|
||||
private String type;
|
||||
private String baseType;
|
||||
private String desc;
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
public String getIpAddr() {
|
||||
return ipAddr;
|
||||
}
|
||||
public void setIpAddr(String ipAddr) {
|
||||
this.ipAddr = ipAddr;
|
||||
}
|
||||
public String getMacAddr() {
|
||||
return macAddr;
|
||||
}
|
||||
public void setMacAddr(String macAddr) {
|
||||
this.macAddr = macAddr;
|
||||
}
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
public String getCommand() {
|
||||
return command;
|
||||
}
|
||||
public void setCommand(String command) {
|
||||
this.command = command;
|
||||
}
|
||||
public String getData() {
|
||||
return data;
|
||||
}
|
||||
public void setData(String data) {
|
||||
this.data = data;
|
||||
}
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
public String getBaseType() {
|
||||
return baseType;
|
||||
}
|
||||
public void setBaseType(String baseType) {
|
||||
this.baseType = baseType;
|
||||
}
|
||||
public String getDesc() {
|
||||
return desc;
|
||||
}
|
||||
public void setDesc(String desc) {
|
||||
this.desc = desc;
|
||||
}
|
||||
public boolean hasIpAndMac() {
|
||||
boolean deviceOk = true;
|
||||
if(ipAddr == null || ipAddr.trim().isEmpty())
|
||||
deviceOk = false;
|
||||
else if(macAddr == null || macAddr.trim().isEmpty())
|
||||
deviceOk = false;
|
||||
else if(type == null || type.trim().isEmpty())
|
||||
deviceOk = false;
|
||||
return deviceOk;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,360 @@
|
||||
package com.bwssystems.HABridge.plugins.broadlink;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.net.BindException;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.InetAddress;
|
||||
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.BridgeSettings;
|
||||
import com.bwssystems.HABridge.BridgeSettingsDescriptor;
|
||||
import com.bwssystems.HABridge.Configuration;
|
||||
import com.bwssystems.HABridge.Home;
|
||||
import com.bwssystems.HABridge.api.CallItem;
|
||||
import com.bwssystems.HABridge.dao.DeviceDescriptor;
|
||||
import com.bwssystems.HABridge.hue.BrightnessDecode;
|
||||
import com.bwssystems.HABridge.hue.ColorData;
|
||||
import com.bwssystems.HABridge.hue.ColorDecode;
|
||||
import com.bwssystems.HABridge.hue.DeviceDataDecode;
|
||||
import com.bwssystems.HABridge.hue.MultiCommandUtil;
|
||||
import com.bwssystems.HABridge.hue.TimeDecode;
|
||||
import com.bwssystems.HABridge.util.HexLibrary;
|
||||
import com.github.mob41.blapi.BLDevice;
|
||||
import com.github.mob41.blapi.MP1Device;
|
||||
import com.github.mob41.blapi.SP1Device;
|
||||
import com.github.mob41.blapi.SP2Device;
|
||||
import com.github.mob41.blapi.mac.Mac;
|
||||
import com.github.mob41.blapi.mac.MacFormatException;
|
||||
import com.github.mob41.blapi.pkt.cmd.rm2.SendDataCmdPayload;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
public class BroadlinkHome implements Home {
|
||||
private static final Logger log = LoggerFactory.getLogger(BroadlinkHome.class);
|
||||
private Map<String, BLDevice> broadlinkMap;
|
||||
private Boolean validBroadlink;
|
||||
private boolean closed;
|
||||
private Boolean isDevMode;
|
||||
private BridgeSettingsDescriptor bridgeSettingsDesc;
|
||||
|
||||
public BroadlinkHome(BridgeSettings bridgeSettings) {
|
||||
super();
|
||||
closed = true;
|
||||
createHome(bridgeSettings);
|
||||
closed = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Home createHome(BridgeSettings bridgeSettings) {
|
||||
broadlinkMap = null;
|
||||
bridgeSettingsDesc = bridgeSettings.getBridgeSettingsDescriptor();
|
||||
validBroadlink = bridgeSettings.getBridgeSettingsDescriptor().isValidBroadlink();
|
||||
isDevMode = Boolean.parseBoolean(System.getProperty("dev.mode", "false"));
|
||||
if (isDevMode)
|
||||
validBroadlink = true;
|
||||
|
||||
if(validBroadlink)
|
||||
broadlinkDiscover();
|
||||
|
||||
log.info("Broadlink Home created." + (validBroadlink ? "" : " No Broadlinks configured.") + (isDevMode ? " DevMode is set." : ""));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getItems(String type) {
|
||||
List<BroadlinkEntry> deviceList = new ArrayList<BroadlinkEntry>();
|
||||
if(!validBroadlink || broadlinkMap == null)
|
||||
return deviceList;
|
||||
BroadlinkEntry theResponse = null;
|
||||
log.debug("consolidating devices for Broadlink");
|
||||
Iterator<String> keys = broadlinkMap.keySet().iterator();
|
||||
while(keys.hasNext()) {
|
||||
String key = keys.next();
|
||||
theResponse = toEntry(broadlinkMap.get(key));
|
||||
if(theResponse != null)
|
||||
deviceList.add(theResponse);
|
||||
else {
|
||||
log.warn("Cannot get BroadlinkDevice with name: " + key + ", skipping this Broadlink.");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return deviceList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh() {
|
||||
if(validBroadlink)
|
||||
broadlinkDiscover();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String deviceHandler(CallItem anItem, MultiCommandUtil aMultiUtil, String lightId, int intensity,
|
||||
Integer targetBri, Integer targetBriInc, ColorData colorData, DeviceDescriptor device, String body) {
|
||||
String theReturn = null;
|
||||
boolean changeState = false;
|
||||
String theStringData = null;
|
||||
log.debug("executing HUE api request to send message to BroadlinkDevice: " + anItem.getItem().toString());
|
||||
if(!validBroadlink) {
|
||||
log.warn("Should not get here, no Broadlinks configured");
|
||||
theReturn = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
|
||||
+ "\",\"description\": \"Should not get here, no LifxDevices configured\", \"parameter\": \"/lights/"
|
||||
+ lightId + "/state\"}}]";
|
||||
|
||||
} else {
|
||||
BroadlinkEntry broadlinkCommand = null;
|
||||
if(anItem.getItem().isJsonObject())
|
||||
broadlinkCommand = new Gson().fromJson(anItem.getItem(), BroadlinkEntry.class);
|
||||
else
|
||||
broadlinkCommand = new Gson().fromJson(anItem.getItem().getAsString().replaceAll("^\"|\"$", ""), BroadlinkEntry.class);
|
||||
BLDevice theDevice = null;
|
||||
if(broadlinkMap != null && !broadlinkMap.isEmpty())
|
||||
theDevice = broadlinkMap.get(broadlinkCommand.getId());
|
||||
|
||||
if (theDevice == null) {
|
||||
if(broadlinkCommand.hasIpAndMac()) {
|
||||
byte[] intBytes = HexLibrary.decodeHexString(broadlinkCommand.getType());
|
||||
BigInteger theBig = new BigInteger(intBytes);
|
||||
int theType = theBig.intValue();
|
||||
try {
|
||||
theDevice = BLDevice.createInstance((short)theType, broadlinkCommand.getIpAddr(), new Mac(broadlinkCommand.getMacAddr()));
|
||||
} catch (MacFormatException e) {
|
||||
log.warn("Could not initialize BroadlinkDevice device due to Mac (" + broadlinkCommand.getId() + ") format exception: " + e.getMessage());
|
||||
theReturn = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
|
||||
+ "\",\"description\": \"Could not initialize BroadlinkDevice device due to Mac format exception\", \"parameter\": \"/lights/"
|
||||
+ lightId + "/state\"}}]";
|
||||
} catch (IOException e) {
|
||||
log.warn("Could not initialize BroadlinkDevice device due to IP Address (" + broadlinkCommand.getId() + ") exception: " + e.getMessage());
|
||||
theReturn = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
|
||||
+ "\",\"description\": \"Could not initialize BroadlinkDevice device due to IP Address exception\", \"parameter\": \"/lights/"
|
||||
+ lightId + "/state\"}}]";
|
||||
} catch (Exception e) {
|
||||
log.warn("Could not initialize BroadlinkDevice device due to (" + broadlinkCommand.getId() + ") exception: " + e.getMessage());
|
||||
theReturn = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
|
||||
+ "\",\"description\": \"Could not initialize BroadlinkDevice device due to exception\", \"parameter\": \"/lights/"
|
||||
+ lightId + "/state\"}}]";
|
||||
}
|
||||
|
||||
if(broadlinkMap == null)
|
||||
broadlinkMap = new HashMap<String, BLDevice>();
|
||||
|
||||
if (theDevice != null) {
|
||||
String newId = theDevice.getHost() + "-" + String.format("%04x", theDevice.getDeviceType());
|
||||
if (broadlinkMap.get(newId) == null) {
|
||||
broadlinkMap.put(newId, theDevice);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (theDevice == null) {
|
||||
log.warn("Should not get here, no BroadlinkDevice not available");
|
||||
theReturn = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
|
||||
+ "\",\"description\": \"Should not get here, no Broadlinks available\", \"parameter\": \"/lights/"
|
||||
+ lightId + "/state\"}}]";
|
||||
} else {
|
||||
log.debug("calling BroadlinkDevice: " + broadlinkCommand.getName());
|
||||
try {
|
||||
if(!isDevMode) {
|
||||
if(!theDevice.auth()) {
|
||||
log.error("Call to " + broadlinkCommand.getId() + " device authorization failed.");
|
||||
theReturn = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
|
||||
+ "\",\"description\": \"" + broadlinkCommand.getId() + " device auth error.\", \"parameter\": \"/lights/"
|
||||
+ lightId + "/state\"}}]";
|
||||
}
|
||||
}
|
||||
switch (theDevice.getDeviceType()) {
|
||||
case BLDevice.DEV_A1:
|
||||
log.debug("Broadlink A1 device called and not supported. No Action, device name = " + device.getName() + ", id= " + broadlinkCommand.getId());
|
||||
break;
|
||||
case BLDevice.DEV_MP1:
|
||||
if(broadlinkCommand.getCommand().equals("on"))
|
||||
changeState = true;
|
||||
else
|
||||
changeState = false;
|
||||
((MP1Device) theDevice).setState(Integer.parseInt(broadlinkCommand.getData()), changeState);
|
||||
break;
|
||||
case BLDevice.DEV_SP2:
|
||||
case BLDevice.DEV_SP2_HONEYWELL_ALT1:
|
||||
case BLDevice.DEV_SP2_HONEYWELL_ALT2:
|
||||
case BLDevice.DEV_SP2_HONEYWELL_ALT3:
|
||||
case BLDevice.DEV_SP2_HONEYWELL_ALT4:
|
||||
case BLDevice.DEV_SPMINI:
|
||||
case BLDevice.DEV_SP3:
|
||||
case BLDevice.DEV_SPMINI2:
|
||||
case BLDevice.DEV_SPMINI_OEM_ALT1:
|
||||
case BLDevice.DEV_SPMINI_OEM_ALT2:
|
||||
case BLDevice.DEV_SPMINI_PLUS:
|
||||
if(broadlinkCommand.getCommand().equals("on"))
|
||||
changeState = true;
|
||||
else
|
||||
changeState = false;
|
||||
((SP2Device) theDevice).setState(changeState);
|
||||
break;
|
||||
case BLDevice.DEV_SP1:
|
||||
if(broadlinkCommand.getCommand().equals("on"))
|
||||
changeState = true;
|
||||
else
|
||||
changeState = false;
|
||||
((SP1Device) theDevice).setPower(changeState);
|
||||
break;
|
||||
case BLDevice.DEV_RM_2:
|
||||
case BLDevice.DEV_RM_MINI:
|
||||
case BLDevice.DEV_RM_PRO_PHICOMM:
|
||||
case BLDevice.DEV_RM_2_HOME_PLUS:
|
||||
case BLDevice.DEV_RM_2_2HOME_PLUS_GDT:
|
||||
case BLDevice.DEV_RM_2_PRO_PLUS:
|
||||
case BLDevice.DEV_RM_2_PRO_PLUS_2:
|
||||
case BLDevice.DEV_RM_2_PRO_PLUS_2_BL:
|
||||
case BLDevice.DEV_RM_MINI_SHATE:
|
||||
if(broadlinkCommand.getData() != null && !broadlinkCommand.getData().trim().isEmpty()) {
|
||||
theStringData = broadlinkCommand.getData().trim();
|
||||
if(targetBri != null || targetBriInc != null) {
|
||||
theStringData = BrightnessDecode.calculateReplaceIntensityValue(theStringData, intensity, targetBri, targetBriInc, true);
|
||||
}
|
||||
if(colorData != null) {
|
||||
theStringData = ColorDecode.replaceColorData(theStringData, colorData, BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc), true);
|
||||
}
|
||||
theStringData = DeviceDataDecode.replaceDeviceData(theStringData, device);
|
||||
theStringData = TimeDecode.replaceTimeValue(theStringData);
|
||||
byte[] theData = HexLibrary.decodeHexString(theStringData);
|
||||
SendDataCmdPayload thePayload = new SendDataCmdPayload(theData);
|
||||
|
||||
DatagramPacket thePacket = theDevice.sendCmdPkt(Configuration.BROADLINK_DISCONVER_TIMEOUT, thePayload);
|
||||
String returnData = null;
|
||||
if(thePacket != null)
|
||||
returnData = HexLibrary.encodeHexString(thePacket.getData());
|
||||
else
|
||||
returnData = "No Data - null";
|
||||
log.debug("RM2 Device data return: <<<" + returnData + ">>>");
|
||||
}
|
||||
else {
|
||||
log.error("Call to " + broadlinkCommand.getId() + " with no data, noop");
|
||||
theReturn = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
|
||||
+ "\",\"description\": \"" + broadlinkCommand.getId() + " could not call device without data.\", \"parameter\": \"/lights/"
|
||||
+ lightId + "/state\"}}]";
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Call to " + broadlinkCommand.getId() + " device failed with exception: " + e.getMessage(), e);
|
||||
theReturn = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
|
||||
+ "\",\"description\": \"" + broadlinkCommand.getId() + " device call error.\", \"parameter\": \"/lights/"
|
||||
+ lightId + "/state\"}}]";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return theReturn;
|
||||
}
|
||||
|
||||
private BroadlinkEntry toEntry(BLDevice broadlinkObject) {
|
||||
short baseType = 0;
|
||||
switch (broadlinkObject.getDeviceType()) {
|
||||
case BLDevice.DEV_MP1:
|
||||
baseType = BLDevice.DEV_MP1;
|
||||
break;
|
||||
case BLDevice.DEV_SP2:
|
||||
case BLDevice.DEV_SP2_HONEYWELL_ALT1:
|
||||
case BLDevice.DEV_SP2_HONEYWELL_ALT2:
|
||||
case BLDevice.DEV_SP2_HONEYWELL_ALT3:
|
||||
case BLDevice.DEV_SP2_HONEYWELL_ALT4:
|
||||
case BLDevice.DEV_SPMINI:
|
||||
case BLDevice.DEV_SP3:
|
||||
case BLDevice.DEV_SPMINI2:
|
||||
case BLDevice.DEV_SPMINI_OEM_ALT1:
|
||||
case BLDevice.DEV_SPMINI_OEM_ALT2:
|
||||
case BLDevice.DEV_SPMINI_PLUS:
|
||||
baseType = BLDevice.DEV_SP2;
|
||||
break;
|
||||
case BLDevice.DEV_SP1:
|
||||
baseType = BLDevice.DEV_SP1;
|
||||
break;
|
||||
case BLDevice.DEV_RM_2:
|
||||
case BLDevice.DEV_RM_MINI:
|
||||
case BLDevice.DEV_RM_PRO_PHICOMM:
|
||||
case BLDevice.DEV_RM_2_HOME_PLUS:
|
||||
case BLDevice.DEV_RM_2_2HOME_PLUS_GDT:
|
||||
case BLDevice.DEV_RM_2_PRO_PLUS:
|
||||
case BLDevice.DEV_RM_2_PRO_PLUS_2:
|
||||
case BLDevice.DEV_RM_2_PRO_PLUS_2_BL:
|
||||
case BLDevice.DEV_RM_MINI_SHATE:
|
||||
baseType = BLDevice.DEV_RM_2;
|
||||
break;
|
||||
}
|
||||
BroadlinkEntry anEntry = new BroadlinkEntry();
|
||||
anEntry.setId(broadlinkObject.getHost() + "-" + String.format("%04x", broadlinkObject.getDeviceType()));
|
||||
anEntry.setName(broadlinkObject.getDeviceDescription());
|
||||
anEntry.setType(String.format("%04x", broadlinkObject.getDeviceType()));
|
||||
anEntry.setBaseType(String.format("%04x", baseType));
|
||||
anEntry.setDesc(BLDevice.getDescOfType(broadlinkObject.getDeviceType()));
|
||||
anEntry.setIpAddr(broadlinkObject.getHost());
|
||||
anEntry.setMacAddr(broadlinkObject.getMac().getMacString());
|
||||
return anEntry;
|
||||
}
|
||||
|
||||
public BLDevice[] broadlinkDiscover () {
|
||||
BLDevice[] clients = null;
|
||||
int aDiscoverPort = Configuration.BROADLINK_DISCOVER_PORT;
|
||||
broadlinkMap = new HashMap<String, BLDevice>();
|
||||
while(aDiscoverPort > 0) {
|
||||
try {
|
||||
log.info("Broadlink discover....");
|
||||
if(isDevMode) {
|
||||
clients = TestBLDevice.discoverDevices(InetAddress.getByName(bridgeSettingsDesc.getUpnpConfigAddress()), aDiscoverPort, Configuration.BROADLINK_DISCONVER_TIMEOUT);
|
||||
}
|
||||
else
|
||||
clients = BLDevice.discoverDevices(InetAddress.getByName(bridgeSettingsDesc.getUpnpConfigAddress()), aDiscoverPort, Configuration.BROADLINK_DISCONVER_TIMEOUT);
|
||||
for(int i = 0; i < clients.length; i++) {
|
||||
if(clients[i].getDeviceType() != BLDevice.DEV_A1 && broadlinkMap.get(clients[i].getHost() + "-" + String.format("%04x", clients[i].getDeviceType())) == null) {
|
||||
broadlinkMap.put(clients[i].getHost() + "-" + String.format("%04x", clients[i].getDeviceType()), clients[i]);
|
||||
log.debug("Adding Device to Map - host: " + clients[i].getHost() + ", device Type: " + clients[i].getDeviceDescription() + ", mac: " + (clients[i].getMac() == null ? "no Mac in client" : clients[i].getMac().getMacString()));
|
||||
} else {
|
||||
log.debug("Ignoring Device (already in the list or an A1 Device) - host: " + clients[i].getHost() + ", device Type: " + clients[i].getDeviceDescription() + ", mac: " + (clients[i].getMac() == null ? "no Mac in client" : clients[i].getMac().getMacString()));
|
||||
}
|
||||
}
|
||||
aDiscoverPort = 0;
|
||||
} catch (BindException e) {
|
||||
log.warn("Could not discover Broadlinks, Port in use, increasing by 11");
|
||||
aDiscoverPort += 11;
|
||||
if(aDiscoverPort > Configuration.BROADLINK_DISCOVER_PORT + 110)
|
||||
aDiscoverPort = 0;
|
||||
} catch (IOException e) {
|
||||
log.warn("Could not discover Broadlinks, with IO Exception", e);
|
||||
broadlinkMap = null;
|
||||
aDiscoverPort = 0;
|
||||
}
|
||||
}
|
||||
if(clients == null || clients.length <= 0) {
|
||||
log.warn("Did not discover any Broadlinks.");
|
||||
broadlinkMap = null;
|
||||
} else {
|
||||
log.info("Broadlink discover found " + clients.length + " clients.");
|
||||
}
|
||||
return clients;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeHome() {
|
||||
if(!validBroadlink)
|
||||
return;
|
||||
log.debug("Closing Home.");
|
||||
if(broadlinkMap != null) {
|
||||
broadlinkMap.clear();
|
||||
broadlinkMap = null;
|
||||
}
|
||||
if(closed) {
|
||||
log.debug("Home is already closed....");
|
||||
return;
|
||||
}
|
||||
closed = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.bwssystems.HABridge.plugins.broadlink;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.InetAddress;
|
||||
|
||||
import com.bwssystems.HABridge.util.HexLibrary;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.github.mob41.blapi.BLDevice;
|
||||
import com.github.mob41.blapi.mac.Mac;
|
||||
import com.github.mob41.blapi.pkt.CmdPayload;
|
||||
|
||||
public class TestBLDevice extends BLDevice {
|
||||
private static final Logger log = LoggerFactory.getLogger(TestBLDevice.class);
|
||||
|
||||
protected TestBLDevice(short deviceType, String deviceDesc, String host, Mac mac) throws IOException {
|
||||
super(deviceType, deviceDesc, host, mac);
|
||||
}
|
||||
|
||||
public void setState(boolean aState) {
|
||||
log.info("setState called with " + aState);
|
||||
}
|
||||
|
||||
public void setState(int anIndex, boolean aState) {
|
||||
log.info("setState called with index " + anIndex + " and state " + aState);
|
||||
}
|
||||
|
||||
public void setPower(boolean aState) {
|
||||
log.info("setPower called with " + aState);
|
||||
}
|
||||
|
||||
public DatagramPacket sendCmdPkt(int timeout, CmdPayload aCmd) {
|
||||
log.info("sendCmdPkt called with " + HexLibrary.encodeHexString(aCmd.getPayload().getData()));
|
||||
return null;
|
||||
}
|
||||
|
||||
public static BLDevice[] discoverDevices(InetAddress theAddress, int aport, int timeout) {
|
||||
TestMP1Device mp1Device = null;
|
||||
TestSP1Device sp1Device = null;
|
||||
TestSP2Device sp2Device = null;
|
||||
TestRM2Device rm2Device = null;
|
||||
try {
|
||||
mp1Device = new TestMP1Device("mp1host", null);
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
sp1Device = new TestSP1Device("sp1host", null);
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
sp2Device = new TestSP2Device("sp2host", null);
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
rm2Device = new TestRM2Device("rm2host", null);
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
BLDevice[] devices = { mp1Device, sp1Device, sp2Device, rm2Device };
|
||||
log.info("Created test devices");
|
||||
return devices;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.bwssystems.HABridge.plugins.broadlink;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramPacket;
|
||||
import com.bwssystems.HABridge.util.HexLibrary;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.github.mob41.blapi.MP1Device;
|
||||
import com.github.mob41.blapi.mac.Mac;
|
||||
import com.github.mob41.blapi.pkt.CmdPayload;
|
||||
|
||||
public class TestMP1Device extends MP1Device {
|
||||
private static final Logger log = LoggerFactory.getLogger(TestMP1Device.class);
|
||||
|
||||
protected TestMP1Device(String host, Mac mac) throws IOException {
|
||||
super(host, mac);
|
||||
}
|
||||
|
||||
public void setState(int anIndex, boolean aState) {
|
||||
log.info("setState called with index " + anIndex + " and state " + aState);
|
||||
}
|
||||
|
||||
public DatagramPacket sendCmdPkt(int timeout, CmdPayload aCmd) {
|
||||
log.info("sendCmdPkt called with " + HexLibrary.encodeHexString(aCmd.getPayload().getData()));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.bwssystems.HABridge.plugins.broadlink;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramPacket;
|
||||
|
||||
import com.bwssystems.HABridge.util.HexLibrary;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.github.mob41.blapi.RM2Device;
|
||||
import com.github.mob41.blapi.mac.Mac;
|
||||
import com.github.mob41.blapi.pkt.CmdPayload;
|
||||
import com.github.mob41.blapi.pkt.cmd.rm2.SendDataCmdPayload;
|
||||
|
||||
public class TestRM2Device extends RM2Device {
|
||||
private static final Logger log = LoggerFactory.getLogger(TestRM2Device.class);
|
||||
|
||||
protected TestRM2Device(String host, Mac mac) throws IOException {
|
||||
super(host, mac);
|
||||
}
|
||||
|
||||
public DatagramPacket sendCmdPkt(int timeout, CmdPayload aCmd) {
|
||||
log.info("sendCmdPkt called with " + HexLibrary.encodeHexString(((SendDataCmdPayload)aCmd).getData()));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.bwssystems.HABridge.plugins.broadlink;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramPacket;
|
||||
|
||||
import com.bwssystems.HABridge.util.HexLibrary;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.github.mob41.blapi.SP1Device;
|
||||
import com.github.mob41.blapi.mac.Mac;
|
||||
import com.github.mob41.blapi.pkt.CmdPayload;
|
||||
|
||||
public class TestSP1Device extends SP1Device {
|
||||
private static final Logger log = LoggerFactory.getLogger(TestSP1Device.class);
|
||||
|
||||
protected TestSP1Device(String host, Mac mac) throws IOException {
|
||||
super(host, mac);
|
||||
}
|
||||
|
||||
public void setPower(boolean aState) {
|
||||
log.info("setPower called with " + aState);
|
||||
}
|
||||
|
||||
public DatagramPacket sendCmdPkt(int timeout, CmdPayload aCmd) {
|
||||
log.info("sendCmdPkt called with " + HexLibrary.encodeHexString(aCmd.getPayload().getData()));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.bwssystems.HABridge.plugins.broadlink;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramPacket;
|
||||
|
||||
import com.bwssystems.HABridge.util.HexLibrary;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.github.mob41.blapi.SP2Device;
|
||||
import com.github.mob41.blapi.mac.Mac;
|
||||
import com.github.mob41.blapi.pkt.CmdPayload;
|
||||
|
||||
public class TestSP2Device extends SP2Device {
|
||||
private static final Logger log = LoggerFactory.getLogger(TestSP2Device.class);
|
||||
|
||||
protected TestSP2Device(String host, Mac mac) throws IOException {
|
||||
super(host, mac);
|
||||
}
|
||||
|
||||
public void setState(boolean aState) {
|
||||
log.info("setState called with " + aState);
|
||||
}
|
||||
|
||||
public DatagramPacket sendCmdPkt(int timeout, CmdPayload aCmd) {
|
||||
log.info("sendCmdPkt called with " + HexLibrary.encodeHexString(aCmd.getPayload().getData()));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -3,12 +3,10 @@ package com.bwssystems.HABridge.plugins.domoticz;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Base64;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.bwssystems.HABridge.NamedIP;
|
||||
import com.bwssystems.HABridge.api.NameValue;
|
||||
import com.bwssystems.HABridge.plugins.http.HTTPHandler;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
@@ -43,7 +41,7 @@ public class DomoticzHandler {
|
||||
theUrl = buildUrl(rootRequest + type + postpend);
|
||||
else
|
||||
theUrl = buildUrl(rootRequest + type);
|
||||
theData = httpClient.doHttpRequest(theUrl, null, null, null, buildHeaders());
|
||||
theData = httpClient.doHttpRequest(theUrl, null, null, null, httpClient.addBasicAuthHeader(null, domoticzAddress));
|
||||
if(theData != null) {
|
||||
log.debug("GET " + type + " DomoticzApiResponse - data: " + theData);
|
||||
theDomoticzApiResponse = new Gson().fromJson(theData, Devices.class);
|
||||
@@ -76,15 +74,7 @@ public class DomoticzHandler {
|
||||
String newUrl = null;
|
||||
|
||||
if(thePayload != null && !thePayload.isEmpty()) {
|
||||
if(domoticzAddress.getSecure() != null && domoticzAddress.getSecure())
|
||||
newUrl = "https://";
|
||||
else
|
||||
newUrl = "http://";
|
||||
|
||||
newUrl = newUrl + domoticzAddress.getIp();
|
||||
|
||||
if(domoticzAddress.getPort() != null && !domoticzAddress.getPort().isEmpty())
|
||||
newUrl = newUrl + ":" + domoticzAddress.getPort();
|
||||
newUrl = domoticzAddress.getHttpPreamble();
|
||||
|
||||
if(thePayload.startsWith("/"))
|
||||
newUrl = newUrl + thePayload;
|
||||
@@ -95,21 +85,6 @@ public class DomoticzHandler {
|
||||
return newUrl;
|
||||
}
|
||||
|
||||
public NameValue[] buildHeaders() {
|
||||
NameValue[] headers = null;
|
||||
|
||||
if(domoticzAddress.getUsername() != null && !domoticzAddress.getUsername().isEmpty()
|
||||
&& domoticzAddress.getPassword() != null && !domoticzAddress.getPassword().isEmpty()) {
|
||||
NameValue theAuth = new NameValue();
|
||||
theAuth.setName("Authorization");
|
||||
String encoding = Base64.getEncoder().encodeToString((domoticzAddress.getUsername() + ":" + domoticzAddress.getPassword()).getBytes());
|
||||
theAuth.setValue("Basic " + encoding);
|
||||
headers = new NameValue[1];
|
||||
headers[0] = theAuth;
|
||||
}
|
||||
|
||||
return headers;
|
||||
}
|
||||
public NamedIP getDomoticzAddress() {
|
||||
return domoticzAddress;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,10 @@ import com.bwssystems.HABridge.api.hue.HueErrorResponse;
|
||||
import com.bwssystems.HABridge.dao.DeviceDescriptor;
|
||||
import com.bwssystems.HABridge.hue.BrightnessDecode;
|
||||
import com.bwssystems.HABridge.hue.ColorData;
|
||||
import com.bwssystems.HABridge.hue.ColorDecode;
|
||||
import com.bwssystems.HABridge.hue.DeviceDataDecode;
|
||||
import com.bwssystems.HABridge.hue.MultiCommandUtil;
|
||||
import com.bwssystems.HABridge.hue.TimeDecode;
|
||||
import com.bwssystems.HABridge.plugins.http.HTTPHandler;
|
||||
import com.bwssystems.HABridge.plugins.http.HTTPHome;
|
||||
import com.google.gson.Gson;
|
||||
@@ -41,7 +44,7 @@ public class DomoticzHome implements Home {
|
||||
public Object getItems(String type) {
|
||||
if(!validDomoticz)
|
||||
return null;
|
||||
log.debug("consolidating devices for hues");
|
||||
log.debug("consolidating devices for Domoticzs");
|
||||
List<DomoticzDevice> theResponse = null;
|
||||
Iterator<String> keys = domoticzs.keySet().iterator();
|
||||
List<DomoticzDevice> deviceList = new ArrayList<DomoticzDevice>();
|
||||
@@ -63,9 +66,14 @@ public class DomoticzHome implements Home {
|
||||
return deviceList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh() {
|
||||
// noop
|
||||
}
|
||||
|
||||
private Boolean addDomoticzDevices(List<DomoticzDevice> theDeviceList, List<DomoticzDevice> theSourceList, String theKey) {
|
||||
if(!validDomoticz)
|
||||
return null;
|
||||
return false;
|
||||
Iterator<DomoticzDevice> devices = theSourceList.iterator();
|
||||
while(devices.hasNext()) {
|
||||
DomoticzDevice theDevice = devices.next();
|
||||
@@ -80,7 +88,7 @@ public class DomoticzHome implements Home {
|
||||
Devices theDomoticzApiResponse = null;
|
||||
String responseString = null;
|
||||
|
||||
String theUrl = anItem.getItem().getAsString();
|
||||
String theUrl = anItem.getItem().getAsString().replaceAll("^\"|\"$", "");
|
||||
if(theUrl != null && !theUrl.isEmpty () && (theUrl.startsWith("http://") || theUrl.startsWith("https://"))) {
|
||||
String intermediate = theUrl.substring(theUrl.indexOf("://") + 3);
|
||||
String hostPortion = intermediate.substring(0, intermediate.indexOf('/'));
|
||||
@@ -95,7 +103,23 @@ public class DomoticzHome implements Home {
|
||||
String theData;
|
||||
String anUrl = BrightnessDecode.calculateReplaceIntensityValue(theUrlBody,
|
||||
intensity, targetBri, targetBriInc, false);
|
||||
theData = httpClient.doHttpRequest(theHandler.buildUrl(anUrl), null, null, null, theHandler.buildHeaders());
|
||||
if (colorData != null) {
|
||||
anUrl = ColorDecode.replaceColorData(anUrl, colorData, BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc), false);
|
||||
}
|
||||
anUrl = DeviceDataDecode.replaceDeviceData(anUrl, device);
|
||||
anUrl = TimeDecode.replaceTimeValue(anUrl);
|
||||
|
||||
String aBody = null;
|
||||
if(anItem.getHttpBody()!= null && !anItem.getHttpBody().isEmpty()) {
|
||||
aBody = BrightnessDecode.calculateReplaceIntensityValue(anItem.getHttpBody(),
|
||||
intensity, targetBri, targetBriInc, false);
|
||||
if (colorData != null) {
|
||||
aBody = ColorDecode.replaceColorData(aBody, colorData, BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc), false);
|
||||
}
|
||||
aBody = DeviceDataDecode.replaceDeviceData(aBody, device);
|
||||
aBody = TimeDecode.replaceTimeValue(aBody);
|
||||
}
|
||||
theData = httpClient.doHttpRequest(theHandler.buildUrl(anUrl), null, null, aBody, httpClient.addBasicAuthHeader(null, theHandler.getDomoticzAddress()));
|
||||
try {
|
||||
theDomoticzApiResponse = new Gson().fromJson(theData, Devices.class);
|
||||
if(theDomoticzApiResponse.getStatus().equals("OK"))
|
||||
@@ -104,25 +128,25 @@ public class DomoticzHome implements Home {
|
||||
log.warn("Call failed for Domoticz " + theHandler.getDomoticzAddress().getName() + " with status " + theDomoticzApiResponse.getStatus() + " for item " + theDomoticzApiResponse.getTitle());
|
||||
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
|
||||
"Error on calling url to change device state", "/lights/"
|
||||
+ lightId + "state", null, null).getTheErrors(), HueError[].class);
|
||||
+ lightId + "/state", null, null).getTheErrors(), HueError[].class);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("Cannot interrpret result from call for Domoticz " + theHandler.getDomoticzAddress().getName() + " as response is not parsable.");
|
||||
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
|
||||
"Error on calling url to change device state", "/lights/"
|
||||
+ lightId + "state", null, null).getTheErrors(), HueError[].class);
|
||||
+ lightId + "/state", null, null).getTheErrors(), HueError[].class);
|
||||
}
|
||||
} else {
|
||||
log.warn("Domoticz Call could not complete, no address found: " + theUrl);
|
||||
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
|
||||
"Error on calling url to change device state", "/lights/"
|
||||
+ lightId + "state", null, null).getTheErrors(), HueError[].class);
|
||||
+ lightId + "/state", null, null).getTheErrors(), HueError[].class);
|
||||
}
|
||||
} else {
|
||||
log.warn("Domoticz Call to be presented as http(s)://<ip_address>(:<port>)/payload, format of request unknown: " + theUrl);
|
||||
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
|
||||
"Error on calling url to change device state", "/lights/"
|
||||
+ lightId + "state", null, null).getTheErrors(), HueError[].class);
|
||||
+ lightId + "/state", null, null).getTheErrors(), HueError[].class);
|
||||
}
|
||||
return responseString;
|
||||
}
|
||||
@@ -167,7 +191,7 @@ public class DomoticzHome implements Home {
|
||||
@Override
|
||||
public void closeHome() {
|
||||
log.debug("Closing Home.");
|
||||
if(closed) {
|
||||
if(closed || !validDomoticz) {
|
||||
log.debug("Home is already closed....");
|
||||
return;
|
||||
}
|
||||
@@ -175,6 +199,7 @@ public class DomoticzHome implements Home {
|
||||
if(httpClient != null)
|
||||
httpClient.closeHandler();
|
||||
|
||||
domoticzs = null;
|
||||
closed = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,13 +31,14 @@ public class CommandHome implements Home {
|
||||
|
||||
@Override
|
||||
public String deviceHandler(CallItem anItem, MultiCommandUtil aMultiUtil, String lightId, int intensity, Integer targetBri, Integer targetBriInc, ColorData colorData, DeviceDescriptor device, String body) {
|
||||
log.debug("Exec Request called with url: " + anItem.getItem().getAsString() + " and exec Garden: " + (theSettings.getBridgeSecurity().getExecGarden() == null ? "not given" : theSettings.getBridgeSecurity().getExecGarden()));
|
||||
String theItem = anItem.getItem().getAsString().replaceAll("^\"|\"$", "");
|
||||
log.debug("Exec Request called with url: {} and exec Garden: {}", theItem, (theSettings.getBridgeSecurity().getExecGarden() == null ? "not given" : theSettings.getBridgeSecurity().getExecGarden()));
|
||||
String responseString = null;
|
||||
String intermediate;
|
||||
if (anItem.getItem().getAsString().contains("exec://"))
|
||||
intermediate = anItem.getItem().getAsString().substring(anItem.getItem().getAsString().indexOf("://") + 3);
|
||||
if (theItem.contains("exec://"))
|
||||
intermediate = theItem.substring(anItem.getItem().getAsString().indexOf("://") + 3);
|
||||
else
|
||||
intermediate = anItem.getItem().getAsString();
|
||||
intermediate = theItem;
|
||||
intermediate = BrightnessDecode.calculateReplaceIntensityValue(intermediate, intensity, targetBri, targetBriInc, false);
|
||||
if (colorData != null) {
|
||||
intermediate = ColorDecode.replaceColorData(intermediate, colorData, BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc), false);
|
||||
@@ -67,13 +68,13 @@ public class CommandHome implements Home {
|
||||
log.warn("Could not execute request: " + anItem + " with message: " + e.getMessage());
|
||||
responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
|
||||
+ "\",\"description\": \"Error on calling out to device\", \"parameter\": \"/lights/" + lightId
|
||||
+ "state\"}}]";
|
||||
+ "/state\"}}]";
|
||||
}
|
||||
} else {
|
||||
log.warn("Could not execute request. Request is empty.");
|
||||
responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
|
||||
+ "\",\"description\": \"Error on calling out to device\", \"parameter\": \"/lights/" + lightId
|
||||
+ "state\"}}]";
|
||||
+ "/state\"}}]";
|
||||
}
|
||||
|
||||
return responseString;
|
||||
@@ -92,6 +93,11 @@ public class CommandHome implements Home {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh() {
|
||||
// noop
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeHome() {
|
||||
log.debug("Closing Home.");
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.bwssystems.HABridge.plugins.fhem;
|
||||
|
||||
public class FHEMCommand {
|
||||
private String url;
|
||||
private String command;
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
public String getCommand() {
|
||||
return command;
|
||||
}
|
||||
public void setCommand(String command) {
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.bwssystems.HABridge.plugins.fhem;
|
||||
|
||||
public class FHEMDevice {
|
||||
|
||||
private String address;
|
||||
private String name;
|
||||
private Result item;
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
public Result getItem() {
|
||||
return item;
|
||||
}
|
||||
public void setItem(Result item) {
|
||||
this.item = item;
|
||||
}
|
||||
}
|
||||
218
src/main/java/com/bwssystems/HABridge/plugins/fhem/FHEMHome.java
Normal file
218
src/main/java/com/bwssystems/HABridge/plugins/fhem/FHEMHome.java
Normal file
@@ -0,0 +1,218 @@
|
||||
package com.bwssystems.HABridge.plugins.fhem;
|
||||
|
||||
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.BridgeSettings;
|
||||
import com.bwssystems.HABridge.DeviceMapTypes;
|
||||
import com.bwssystems.HABridge.Home;
|
||||
import com.bwssystems.HABridge.NamedIP;
|
||||
import com.bwssystems.HABridge.api.CallItem;
|
||||
import com.bwssystems.HABridge.api.hue.HueError;
|
||||
import com.bwssystems.HABridge.api.hue.HueErrorResponse;
|
||||
import com.bwssystems.HABridge.dao.DeviceDescriptor;
|
||||
import com.bwssystems.HABridge.hue.BrightnessDecode;
|
||||
import com.bwssystems.HABridge.hue.ColorData;
|
||||
import com.bwssystems.HABridge.hue.ColorDecode;
|
||||
import com.bwssystems.HABridge.hue.DeviceDataDecode;
|
||||
import com.bwssystems.HABridge.hue.MultiCommandUtil;
|
||||
import com.bwssystems.HABridge.hue.TimeDecode;
|
||||
import com.bwssystems.HABridge.plugins.http.HTTPHandler;
|
||||
import com.bwssystems.HABridge.plugins.http.HTTPHome;
|
||||
import com.bwssystems.HABridge.plugins.http.HttpTestHandler;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
|
||||
public class FHEMHome implements Home {
|
||||
private static final Logger log = LoggerFactory.getLogger(FHEMHome.class);
|
||||
private Map<String, FHEMInstance> fhemMap;
|
||||
private Boolean validFhem;
|
||||
private Boolean isDevMode;
|
||||
private HTTPHandler httpClient;
|
||||
private boolean closed;
|
||||
|
||||
public FHEMHome(BridgeSettings bridgeSettings) {
|
||||
super();
|
||||
closed = true;
|
||||
createHome(bridgeSettings);
|
||||
closed = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String deviceHandler(CallItem anItem, MultiCommandUtil aMultiUtil, String lightId, int intensity,
|
||||
Integer targetBri, Integer targetBriInc, ColorData colorData, DeviceDescriptor device, String body) {
|
||||
|
||||
JsonElement jsonUrl = anItem.getItem();
|
||||
String theUrl = jsonUrl.toString();
|
||||
String responseString = null;
|
||||
|
||||
if(theUrl != null && !theUrl.isEmpty()) {
|
||||
FHEMCommand theCommand = null;
|
||||
try {
|
||||
if(anItem.getItem().isJsonObject())
|
||||
theCommand = new Gson().fromJson(anItem.getItem(), FHEMCommand.class);
|
||||
else
|
||||
theCommand = new Gson().fromJson(anItem.getItem().getAsString().replaceAll("^\"|\"$", ""), FHEMCommand.class);
|
||||
} catch(Exception e) {
|
||||
log.warn("Cannot parse command to FHEM <<<" + theUrl + ">>>", e);
|
||||
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
|
||||
"Error on calling url to change device state", "/lights/"
|
||||
+ lightId + "/state", null, null).getTheErrors(), HueError[].class);
|
||||
return responseString;
|
||||
}
|
||||
String intermediate = theCommand.getUrl().substring(theCommand.getUrl().indexOf("://") + 3);
|
||||
String hostPortion = intermediate.substring(0, intermediate.indexOf('/'));
|
||||
String theUrlBody = intermediate.substring(intermediate.indexOf('/') + 1);
|
||||
String hostAddr = null;
|
||||
if (hostPortion.contains(":")) {
|
||||
hostAddr = hostPortion.substring(0, intermediate.indexOf(':'));
|
||||
} else
|
||||
hostAddr = hostPortion;
|
||||
FHEMInstance theHandler = findHandlerByAddress(hostAddr);
|
||||
if(theHandler != null) {
|
||||
String anUrl = BrightnessDecode.calculateReplaceIntensityValue(theUrlBody,
|
||||
intensity, targetBri, targetBriInc, false);
|
||||
if (colorData != null) {
|
||||
anUrl = ColorDecode.replaceColorData(anUrl, colorData, BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc), false);
|
||||
}
|
||||
anUrl = DeviceDataDecode.replaceDeviceData(anUrl, device);
|
||||
anUrl = TimeDecode.replaceTimeValue(anUrl);
|
||||
|
||||
String aCommand = null;
|
||||
if(theCommand.getCommand() != null && !theCommand.getCommand().isEmpty()) {
|
||||
aCommand = BrightnessDecode.calculateReplaceIntensityValue(theCommand.getCommand(),
|
||||
intensity, targetBri, targetBriInc, false);
|
||||
if (colorData != null) {
|
||||
aCommand = ColorDecode.replaceColorData(aCommand, colorData, BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc), false);
|
||||
}
|
||||
aCommand = DeviceDataDecode.replaceDeviceData(aCommand, device);
|
||||
aCommand = TimeDecode.replaceTimeValue(aCommand);
|
||||
}
|
||||
try {
|
||||
theHandler.callCommand(anUrl, aCommand, httpClient);
|
||||
} catch (Exception e) {
|
||||
log.warn("Cannot send comand to FHEM", e);
|
||||
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
|
||||
"Error on calling url to change device state", "/lights/"
|
||||
+ lightId + "state", null, null).getTheErrors(), HueError[].class);
|
||||
}
|
||||
} else {
|
||||
log.warn("FHEM Call could not complete, no address found: " + theUrl);
|
||||
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
|
||||
"Error on calling url to change device state", "/lights/"
|
||||
+ lightId + "state", null, null).getTheErrors(), HueError[].class);
|
||||
}
|
||||
} else {
|
||||
log.warn("FHEM Call to be presented as http(s)://<ip_address>(:<port>)/payload, format of request unknown: " + theUrl);
|
||||
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
|
||||
"Error on calling url to change device state", "/lights/"
|
||||
+ lightId + "state", null, null).getTheErrors(), HueError[].class);
|
||||
}
|
||||
return responseString;
|
||||
}
|
||||
|
||||
private FHEMInstance findHandlerByAddress(String hostAddress) {
|
||||
FHEMInstance aHandler = null;
|
||||
boolean found = false;
|
||||
Iterator<String> keys = fhemMap.keySet().iterator();
|
||||
while(keys.hasNext()) {
|
||||
String key = keys.next();
|
||||
aHandler = fhemMap.get(key);
|
||||
if(aHandler != null && aHandler.getFhemAddress().getIp().equals(hostAddress)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found)
|
||||
aHandler = null;
|
||||
return aHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getItems(String type) {
|
||||
|
||||
if(!validFhem)
|
||||
return null;
|
||||
log.debug("consolidating devices for FHEM");
|
||||
List<FHEMDevice> theResponse = null;
|
||||
Iterator<String> keys = fhemMap.keySet().iterator();
|
||||
List<FHEMDevice> deviceList = new ArrayList<FHEMDevice>();
|
||||
while(keys.hasNext()) {
|
||||
String key = keys.next();
|
||||
theResponse = fhemMap.get(key).getDevices(httpClient);
|
||||
if(theResponse != null)
|
||||
addFHEMDevices(deviceList, theResponse, key);
|
||||
else {
|
||||
log.warn("Cannot get devices for FHEM: " + key + ", skipping this FHEM.");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return deviceList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh() {
|
||||
// noop
|
||||
}
|
||||
|
||||
private Boolean addFHEMDevices(List<FHEMDevice> theDeviceList, List<FHEMDevice> theSourceList, String theKey) {
|
||||
Iterator<FHEMDevice> devices = theSourceList.iterator();
|
||||
while(devices.hasNext()) {
|
||||
FHEMDevice theDevice = devices.next();
|
||||
theDeviceList.add(theDevice);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Home createHome(BridgeSettings bridgeSettings) {
|
||||
isDevMode = Boolean.parseBoolean(System.getProperty("dev.mode", "false"));
|
||||
fhemMap = null;
|
||||
validFhem = bridgeSettings.getBridgeSettingsDescriptor().isValidFhem();
|
||||
log.info("FHEM Home created." + (validFhem ? "" : " No FHEMs configured.") + (isDevMode ? " DevMode is set." : ""));
|
||||
if(validFhem) {
|
||||
fhemMap = new HashMap<String,FHEMInstance>();
|
||||
httpClient = HTTPHome.getHandler();
|
||||
if(isDevMode) {
|
||||
httpClient = new HttpTestHandler();
|
||||
((HttpTestHandler)httpClient).setTheData("cmd=jsonlist2", FHEMTestData.TestData);
|
||||
((HttpTestHandler)httpClient).setTheData("set", "FHEM Command Received");
|
||||
((HttpTestHandler)httpClient).setTheData(null, "FHEM no match");
|
||||
}
|
||||
httpClient.setCallType(DeviceMapTypes.FHEM_DEVICE[DeviceMapTypes.typeIndex]);
|
||||
Iterator<NamedIP> theList = bridgeSettings.getBridgeSettingsDescriptor().getFhemaddress().getDevices().iterator();
|
||||
while(theList.hasNext() && validFhem) {
|
||||
NamedIP aFhem = theList.next();
|
||||
try {
|
||||
fhemMap.put(aFhem.getName(), new FHEMInstance(aFhem));
|
||||
} catch (Exception e) {
|
||||
log.error("Cannot get FHEM (" + aFhem.getName() + ") setup, Exiting with message: " + e.getMessage(), e);
|
||||
validFhem = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeHome() {
|
||||
log.debug("Closing Home.");
|
||||
if(!closed && validFhem) {
|
||||
log.debug("Home is already closed....");
|
||||
return;
|
||||
}
|
||||
|
||||
if(httpClient != null)
|
||||
httpClient.closeHandler();
|
||||
|
||||
fhemMap = null;
|
||||
closed = true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
package com.bwssystems.HABridge.plugins.fhem;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.bwssystems.HABridge.NamedIP;
|
||||
import com.bwssystems.HABridge.api.NameValue;
|
||||
import com.bwssystems.HABridge.plugins.http.HTTPHandler;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
public class FHEMInstance {
|
||||
private static final Logger log = LoggerFactory.getLogger(FHEMInstance.class);
|
||||
private NamedIP theFhem;
|
||||
|
||||
public FHEMInstance(NamedIP fhemLocation) {
|
||||
super();
|
||||
theFhem = fhemLocation;
|
||||
}
|
||||
|
||||
public NamedIP getFhemAddress() {
|
||||
return theFhem;
|
||||
}
|
||||
|
||||
public void setFhemAddress(NamedIP fhemAddress) {
|
||||
this.theFhem = fhemAddress;
|
||||
}
|
||||
|
||||
public Boolean callCommand(String aCommand, String commandData, HTTPHandler httpClient) {
|
||||
String aUrl = null;
|
||||
NameValue[] headers = null;
|
||||
/* Trying new code helpers
|
||||
if(theFhem.getSecure() != null && theFhem.getSecure())
|
||||
aUrl = "https://";
|
||||
else
|
||||
aUrl = "http://";
|
||||
if(theFhem.getUsername() != null && !theFhem.getUsername().isEmpty() && theFhem.getPassword() != null && !theFhem.getPassword().isEmpty()) {
|
||||
aUrl = aUrl + theFhem.getUsername() + ":" + theFhem.getPassword() + "@";
|
||||
}
|
||||
aUrl = aUrl + theFhem.getIp() + ":" + theFhem.getPort() + "/" + aCommand + commandData;
|
||||
*/
|
||||
// New style http creation
|
||||
aUrl = theFhem.getHttpPreamble() + "/" + aCommand + commandData;
|
||||
headers = httpClient.addBasicAuthHeader(null, theFhem);
|
||||
log.debug("calling FHEM: " + aUrl);
|
||||
String theData = httpClient.doHttpRequest(aUrl, HttpPost.METHOD_NAME, "text/plain", null, headers);
|
||||
if(theData != null)
|
||||
log.debug("doHttpRequest returned data: <" + theData + ">");
|
||||
return true;
|
||||
}
|
||||
|
||||
public List<FHEMDevice> getDevices(HTTPHandler httpClient) {
|
||||
List<FHEMDevice> deviceList = null;
|
||||
FHEMItem theFhemStates;
|
||||
String theUrl = null;
|
||||
String theData;
|
||||
NameValue[] headers = null;
|
||||
/* Trying new code helpers
|
||||
if(theFhem.getSecure() != null && theFhem.getSecure())
|
||||
theUrl = "https://";
|
||||
else
|
||||
theUrl = "http://";
|
||||
if(theFhem.getUsername() != null && !theFhem.getUsername().isEmpty() && theFhem.getPassword() != null && !theFhem.getPassword().isEmpty()) {
|
||||
theUrl = theUrl + theFhem.getUsername() + ":" + theFhem.getPassword() + "@";
|
||||
}
|
||||
theUrl = theUrl + theFhem.getIp() + ":" + theFhem.getPort() + "/fhem?cmd=jsonlist2";
|
||||
*/
|
||||
theUrl = theFhem.getHttpPreamble() + "/fhem?cmd=jsonlist2";
|
||||
headers = httpClient.addBasicAuthHeader(null, theFhem);
|
||||
if(theFhem.getWebhook() != null && !theFhem.getWebhook().trim().isEmpty())
|
||||
theUrl = theUrl + "%20room=" + theFhem.getWebhook().trim();
|
||||
theData = httpClient.doHttpRequest(theUrl, HttpGet.METHOD_NAME, "application/json", null, headers);
|
||||
if(theData != null) {
|
||||
log.debug("GET FHEM States - data: " + theData);
|
||||
theData = getJSONData(theData);
|
||||
theFhemStates = new Gson().fromJson(theData, FHEMItem.class);
|
||||
if(theFhemStates == null) {
|
||||
log.warn("Cannot get any devices for FHEM " + theFhem.getName() + " as response is not parsable.");
|
||||
}
|
||||
else {
|
||||
deviceList = new ArrayList<FHEMDevice>();
|
||||
|
||||
for (Result aResult:theFhemStates.getResults()) {
|
||||
String name = aResult.getName();
|
||||
if(name.contains("<a href=")) {
|
||||
name = name.substring(name.indexOf("<a href=") + name.indexOf(">"));
|
||||
name = name.substring(1, name.indexOf("</a"));
|
||||
aResult.setName(name);
|
||||
}
|
||||
FHEMDevice aNewFhemDeviceDevice = new FHEMDevice();
|
||||
aNewFhemDeviceDevice.setItem(aResult);
|
||||
aNewFhemDeviceDevice.setAddress(theFhem.getIp() + ":" + theFhem.getPort());
|
||||
aNewFhemDeviceDevice.setName(theFhem.getName());
|
||||
deviceList.add(aNewFhemDeviceDevice);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
log.warn("Cannot get an devices for FHEM " + theFhem.getName() + " http call failed.");
|
||||
return deviceList;
|
||||
}
|
||||
|
||||
public String getJSONData(String response) {
|
||||
String theData;
|
||||
theData = response.substring(response.indexOf("<pre>") + 4);
|
||||
theData = theData.substring(1, theData.indexOf("</pre>") - 1);
|
||||
theData = theData.replace("\n", "");
|
||||
theData = theData.replace("\r", "");
|
||||
theData = theData.replace("<a href=\"", "<a href=\\\"");
|
||||
theData = theData.replace("\">", "\\\">");
|
||||
return theData;
|
||||
}
|
||||
|
||||
protected void closeClient() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
|
||||
package com.bwssystems.HABridge.plugins.fhem;
|
||||
|
||||
import java.util.List;
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class FHEMItem {
|
||||
|
||||
@SerializedName("Arg")
|
||||
@Expose
|
||||
private String arg;
|
||||
@SerializedName("Results")
|
||||
@Expose
|
||||
private List<Result> results = null;
|
||||
@SerializedName("totalResultsReturned")
|
||||
@Expose
|
||||
private Integer totalResultsReturned;
|
||||
|
||||
public String getArg() {
|
||||
return arg;
|
||||
}
|
||||
|
||||
public void setArg(String arg) {
|
||||
this.arg = arg;
|
||||
}
|
||||
|
||||
public List<Result> getResults() {
|
||||
return results;
|
||||
}
|
||||
|
||||
public void setResults(List<Result> results) {
|
||||
this.results = results;
|
||||
}
|
||||
|
||||
public Integer getTotalResultsReturned() {
|
||||
return totalResultsReturned;
|
||||
}
|
||||
|
||||
public void setTotalResultsReturned(Integer totalResultsReturned) {
|
||||
this.totalResultsReturned = totalResultsReturned;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,288 @@
|
||||
package com.bwssystems.HABridge.plugins.fhem;
|
||||
|
||||
public class FHEMTestData {
|
||||
public final static String TestData = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n" +
|
||||
"<html xmlns=\"http://www.w3.org/1999/xhtml\">\n" +
|
||||
" <head root=\"/fhem\">\n" +
|
||||
" <title>Home, Sweet Home</title>\n" +
|
||||
" <link rel=\"shortcut icon\" href=\"/fhem/icons/favicon\" />\n" +
|
||||
" <meta charset=\"UTF-8\">\n" +
|
||||
" <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n" +
|
||||
" <link href=\"/fhem/pgm2/style.css?v=1513026539\" rel=\"stylesheet\"/>\n" +
|
||||
" <link href=\"/fhem/pgm2/jquery-ui.min.css\" rel=\"stylesheet\"/>\n" +
|
||||
" <script attr='' type=\"text/javascript\" src=\"/fhem/pgm2/jquery.min.js\"></script>\n" +
|
||||
" <script attr='' type=\"text/javascript\" src=\"/fhem/pgm2/jquery-ui.min.js\"></script>\n" +
|
||||
" <script attr='' type=\"text/javascript\" src=\"/fhem/pgm2/fhemweb.js\"></script>\n" +
|
||||
" <script attr='' type=\"text/javascript\" src=\"/fhem/pgm2/fhemweb_colorpicker.js\"></script>\n" +
|
||||
" <script attr='' type=\"text/javascript\" src=\"/fhem/pgm2/fhemweb_fbcalllist.js\"></script>\n" +
|
||||
" <script attr='' type=\"text/javascript\" src=\"/fhem/pgm2/fhemweb_knob.js\"></script>\n" +
|
||||
" <script attr='' type=\"text/javascript\" src=\"/fhem/pgm2/fhemweb_readingsGroup.js\"></script>\n" +
|
||||
" <script attr='' type=\"text/javascript\" src=\"/fhem/pgm2/fhemweb_readingsHistory.js\"></script>\n" +
|
||||
" <script attr='' type=\"text/javascript\" src=\"/fhem/pgm2/fhemweb_sortable.js\"></script>\n" +
|
||||
" <script attr='' type=\"text/javascript\" src=\"/fhem/pgm2/fhemweb_uzsu.js\"></script>\n" +
|
||||
" <script attr='' type=\"text/javascript\" src=\"/fhem/pgm2/fhemweb_weekprofile.js\"></script>\n" +
|
||||
" </head>\n" +
|
||||
" <body name='Home, Sweet Home' fw_id='7880' generated=\"1513272732\" longpoll=\"1\" data-confirmDelete='1' data-confirmJSError='1' data-webName='haBridgeWeb '>\n" +
|
||||
" <div id=\"menuScrollArea\">\n" +
|
||||
" <div>\n" +
|
||||
" <a href=\"/fhem?\">\n" +
|
||||
" <div id=\"logo\"></div>\n" +
|
||||
" </a>\n" +
|
||||
" </div>\n" +
|
||||
" <div id=\"menu\">\n" +
|
||||
" <table>\n" +
|
||||
" <tr>\n" +
|
||||
" <td>\n" +
|
||||
" <table class=\"room roomBlock1\">\n" +
|
||||
" <tr>\n" +
|
||||
" <td>\n" +
|
||||
" <div class=\"menu_Save_config\">\n" +
|
||||
" <a href=\"/fhem?cmd=save\">Save config</a>\n" +
|
||||
" <a id=\"saveCheck\" class=\"changed\" style=\"visibility:visible\">?</a>\n" +
|
||||
" </div>\n" +
|
||||
" </td>\n" +
|
||||
" </tr>\n" +
|
||||
" </table>\n" +
|
||||
" </td>\n" +
|
||||
" </tr>\n" +
|
||||
" <tr>\n" +
|
||||
" <td>\n" +
|
||||
" <table class=\"room roomBlock2\">\n" +
|
||||
" <tr>\n" +
|
||||
" <td>\n" +
|
||||
" <div class=\"menu_Alexa\">\n" +
|
||||
" <a href=\"/fhem?room=Alexa\">Alexa</a>\n" +
|
||||
" </div>\n" +
|
||||
" </td>\n" +
|
||||
" </tr>\n" +
|
||||
" <tr>\n" +
|
||||
" <td>\n" +
|
||||
" <div class=\"menu_System\">\n" +
|
||||
" <a href=\"/fhem?room=System\">System</a>\n" +
|
||||
" </div>\n" +
|
||||
" </td>\n" +
|
||||
" </tr>\n" +
|
||||
" <tr>\n" +
|
||||
" <td>\n" +
|
||||
" <div class=\"menu_WG_Zimmer\">\n" +
|
||||
" <a href=\"/fhem?room=WG%2dZimmer\">WG-Zimmer</a>\n" +
|
||||
" </div>\n" +
|
||||
" </td>\n" +
|
||||
" </tr>\n" +
|
||||
" <tr>\n" +
|
||||
" <td>\n" +
|
||||
" <div class=\"menu_habridge\">\n" +
|
||||
" <a href=\"/fhem?room=habridge\">habridge</a>\n" +
|
||||
" </div>\n" +
|
||||
" </td>\n" +
|
||||
" </tr>\n" +
|
||||
" <tr>\n" +
|
||||
" <td>\n" +
|
||||
" <div class=\"menu_Everything\">\n" +
|
||||
" <a href=\"/fhem?room=all\">\n" +
|
||||
" <img class='icon icoEverything' src=\"/fhem/images/default/icoEverything.png\" alt=\"icoEverything\" title=\"icoEverything\"> Everything\n" +
|
||||
" </a>\n" +
|
||||
" </div>\n" +
|
||||
" </td>\n" +
|
||||
" </tr>\n" +
|
||||
" </table>\n" +
|
||||
" </td>\n" +
|
||||
" </tr>\n" +
|
||||
" <tr>\n" +
|
||||
" <td>\n" +
|
||||
" <table class=\"room roomBlock3\">\n" +
|
||||
" <tr>\n" +
|
||||
" <td>\n" +
|
||||
" <div class=\"menu_Logfile\">\n" +
|
||||
" <a href=\"/fhem/FileLog_logWrapper?dev=Logfile&type=text&file=fhem-2017-12.log\">Logfile</a>\n" +
|
||||
" </div>\n" +
|
||||
" </td>\n" +
|
||||
" </tr>\n" +
|
||||
" <tr>\n" +
|
||||
" <td>\n" +
|
||||
" <div>\n" +
|
||||
" <a href=\"/fhem/docs/commandref.html\" target=\"_blank\" >Commandref</a>\n" +
|
||||
" </div>\n" +
|
||||
" </td>\n" +
|
||||
" </tr>\n" +
|
||||
" <tr>\n" +
|
||||
" <td>\n" +
|
||||
" <div>\n" +
|
||||
" <a href=\"http://fhem.de/fhem.html#Documentation\" target=\"_blank\" >Remote doc</a>\n" +
|
||||
" </div>\n" +
|
||||
" </td>\n" +
|
||||
" </tr>\n" +
|
||||
" <tr>\n" +
|
||||
" <td>\n" +
|
||||
" <div class=\"menu_Edit_files\">\n" +
|
||||
" <a href=\"/fhem?cmd=style%20list\">Edit files</a>\n" +
|
||||
" </div>\n" +
|
||||
" </td>\n" +
|
||||
" </tr>\n" +
|
||||
" <tr>\n" +
|
||||
" <td>\n" +
|
||||
" <div class=\"menu_Select_style\">\n" +
|
||||
" <a href=\"/fhem?cmd=style%20select\">Select style</a>\n" +
|
||||
" </div>\n" +
|
||||
" </td>\n" +
|
||||
" </tr>\n" +
|
||||
" <tr>\n" +
|
||||
" <td>\n" +
|
||||
" <div class=\"menu_Event_monitor\">\n" +
|
||||
" <a href=\"/fhem?cmd=style%20eventMonitor\">Event monitor</a>\n" +
|
||||
" </div>\n" +
|
||||
" </td>\n" +
|
||||
" </tr>\n" +
|
||||
" </table>\n" +
|
||||
" </td>\n" +
|
||||
" </tr>\n" +
|
||||
" </table>\n" +
|
||||
" </div>\n" +
|
||||
" </div>\n" +
|
||||
" <div id=\"hdr\">\n" +
|
||||
" <table border=\"0\" class=\"header\">\n" +
|
||||
" <tr>\n" +
|
||||
" <td style=\"padding:0\">\n" +
|
||||
" <form method=\"post\" action=\"/fhem\">\n" +
|
||||
" <input type=\"hidden\" name=\"fw_id\" value=\"7880\"/>\n" +
|
||||
" <input type=\"text\" name=\"cmd\" class=\"maininput\" size=\"40\" value=\"\"/>\n" +
|
||||
" </form>\n" +
|
||||
" </td>\n" +
|
||||
" </tr>\n" +
|
||||
" </table>\n" +
|
||||
" </div>\n" +
|
||||
" <div id='content' >\n" +
|
||||
" <pre>{ \n" +
|
||||
" \"Arg\":\"room=habridge\", \n" +
|
||||
" \"Results\": [ \n" +
|
||||
" { \n" +
|
||||
" \"Name\":\"Arbeitslicht\", \n" +
|
||||
" \"PossibleSets\":\"on off\", \n" +
|
||||
" \"PossibleAttrs\":\"alias comment:textField-long eventMap group room suppressReading userReadings:textField-long verbose:0,1,2,3,4,5 readingList setList useSetExtensions disable disabledForIntervals event-on-change-reading event-on-update-reading event-aggregator event-min-interval stateFormat:textField-long timestamp-on-change-reading alexaName alexaRoom cmdIcon devStateIcon devStateStyle fhem_widget_command fhem_widget_command_2 fhem_widget_command_3 genericDeviceType:security,ignore,switch,outlet,light,blind,thermometer,thermostat,contact,garage,window,lock homebridgeMapping:textField-long icon sortby webCmd widgetOverride userattr\", \n" +
|
||||
" \"Internals\": { \n" +
|
||||
" \"NAME\": \"Arbeitslicht\", \n" +
|
||||
" \"NR\": \"28\", \n" +
|
||||
" \"STATE\": \"-\", \n" +
|
||||
" \"TYPE\": \"dummy\" \n" +
|
||||
" }, \n" +
|
||||
" \"Readings\": { \"state\": { \"Value\":\"on\", \"Time\":\"2017-12-14 15:41:05\" } }, \n" +
|
||||
" \"Attributes\": { \n" +
|
||||
" \"alexaName\": \"Arbeitslicht\", \n" +
|
||||
" \"alexaRoom\": \"alexaroom\", \n" +
|
||||
" \"fhem_widget_command\": \"{ \\u0022allowed_values\\u0022 : [ \\u0022on\\u0022 ], \\u0022order\\u0022 : 0}\", \n" +
|
||||
" \"icon\": \"scene_office\", \n" +
|
||||
" \"room\": \"Alexa,habridge\", \n" +
|
||||
" \"setList\": \"on off\", \n" +
|
||||
" \"stateFormat\": \"-\", \n" +
|
||||
" \"webCmd\": \"on\" \n" +
|
||||
" } \n" +
|
||||
" }, \n" +
|
||||
" { \n" +
|
||||
" \"Name\":\"DeckenlampeLinks\", \n" +
|
||||
" \"PossibleSets\":\"on off dim dimup dimdown HSV RGB sync pair unpair\", \n" +
|
||||
" \"PossibleAttrs\":\"alias comment:textField-long eventMap group room suppressReading userReadings:textField-long verbose:0,1,2,3,4,5 gamma dimStep defaultColor defaultRamp colorCast whitePoint event-on-change-reading event-on-update-reading event-aggregator event-min-interval stateFormat:textField-long timestamp-on-change-reading alexaName alexaRoom cmdIcon devStateIcon devStateStyle fhem_widget_command fhem_widget_command_2 fhem_widget_command_3 genericDeviceType:security,ignore,switch,outlet,light,blind,thermometer,thermostat,contact,garage,window,lock homebridgeMapping:textField-long icon sortby webCmd widgetOverride \n" +
|
||||
" <a href=\"/fhem?detail=AlleLampen\">AlleLampen</a> AlleLampen_map\n" +
|
||||
" <a href=\"/fhem?detail=DeckenLampen\">DeckenLampen</a> DeckenLampen_map structexclude userattr\", \n" +
|
||||
" \"Internals\": { \n" +
|
||||
" \"CONNECTION\": \"bridge-V3\", \n" +
|
||||
" \"DEF\": \"RGBW2 bridge-V3:10.2.3.3\", \n" +
|
||||
" \"IP\": \"10.2.3.3\", \n" +
|
||||
" \"LEDTYPE\": \"RGBW2\", \n" +
|
||||
" \"NAME\": \"DeckenlampeLinks\", \n" +
|
||||
" \"NR\": \"18\", \n" +
|
||||
" \"NTFY_ORDER\": \"50-DeckenlampeLinks\", \n" +
|
||||
" \"PORT\": \"8899\", \n" +
|
||||
" \"PROTO\": \"0\", \n" +
|
||||
" \"SLOT\": \"5\", \n" +
|
||||
" \"STATE\": \"off\", \n" +
|
||||
" \"TYPE\": \"WifiLight\" \n" +
|
||||
" }, \n" +
|
||||
" \"Readings\": { \n" +
|
||||
" \"RGB\": { \"Value\":\"000000\", \"Time\":\"2017-12-14 15:41:10\" }, \n" +
|
||||
" \"brightness\": { \"Value\":\"0\", \"Time\":\"2017-12-14 15:41:10\" }, \n" +
|
||||
" \"hue\": { \"Value\":\"0\", \"Time\":\"2017-12-14 15:41:10\" }, \n" +
|
||||
" \"saturation\": { \"Value\":\"0\", \"Time\":\"2017-12-14 15:41:10\" }, \n" +
|
||||
" \"state\": { \"Value\":\"off\", \"Time\":\"2017-12-14 15:41:10\" } \n" +
|
||||
" }, \n" +
|
||||
" \"Attributes\": { \n" +
|
||||
" \"AlleLampen\": \"AlleLampen\", \n" +
|
||||
" \"DeckenLampen\": \"DeckenLampen\", \n" +
|
||||
" \"fhem_widget_command\": \"{ \\u0022locations\\u0022 : [ \\u0022APP\\u0022, \\u0022WATCH\\u0022, \\u0022WIDGET\\u0022 ], \\u0022allowed_values\\u0022 : [ \\u0022off\\u0022, \\u0022on\\u0022 ], \\u0022order\\u0022 : 6}\", \n" +
|
||||
" \"room\": \"habridge,Alexa,WG-Zimmer\", \n" +
|
||||
" \"userattr\": \"AlleLampen AlleLampen_map\n" +
|
||||
" <a href=\"/fhem?detail=DeckenLampen\">DeckenLampen</a> DeckenLampen_map structexclude\", \n" +
|
||||
" \"webCmd\": \"RGB\", \n" +
|
||||
" \"widgetOverride\": \"RGB:colorpicker,RGB\" \n" +
|
||||
" } \n" +
|
||||
" } ], \n" +
|
||||
" \"totalResultsReturned\":2 \n" +
|
||||
"}\n" +
|
||||
" </pre>\n" +
|
||||
" </div>\n" +
|
||||
" </body>\n" +
|
||||
"</html>";
|
||||
|
||||
public final static String TestData2 = " <div id='content' >\n" +
|
||||
" <pre>\n" + "{ \"Arg\":\"room=HaBridge\", \"Results\": [ { \"Name\":\"wifi_steckdose3\", \"PossibleSets\":\"on:noArg off:noArg off on toggle\", \"PossibleAttrs\":\"alias comment:textField-long eventMap group room suppressReading userReadings:textField-long verbose:0,1,2,3,4,5 IODev qos retain publishSet publishSet_.* subscribeReading_.* autoSubscribeReadings event-on-change-reading event-on-update-reading event-aggregator event-min-interval stateFormat:textField-long timestamp-on-change-reading alarmDevice:Actor,Sensor alarmSettings cmdIcon devStateIcon devStateStyle icon lightSceneParamsToSave lightSceneRestoreOnlyIfChanged:1,0 sortby structexclude webCmd webCmdLabel:textField-long widgetOverride userattr\", \"Internals\": { \"CHANGED\": \"null\", \"NAME\": \"wifi_steckdose3\", \"NR\": \"270\", \"STATE\": \"off\", \"TYPE\": \"MQTT_DEVICE\", \"retain\": \"*:1 \" }, \"Readings\": { \"state\": { \"Value\":\"OFF\", \"Time\":\"2018-01-01 23:01:21\" }, \"transmission-state\": { \"Value\":\"subscription acknowledged\", \"Time\":\"2018-01-03 22:34:00\" } }, \"Attributes\": { \"IODev\": \"myBroker\", \"alias\": \"Stecki\", \"devStateIcon\": \"on:black_Steckdose.on off:black_Steckdose.off\", \"event-on-change-reading\": \"state\", \"eventMap\": \"ON:on OFF:off\", \"publishSet\": \"on off toggle /SmartHome/az/stecker/cmnd/POWER\", \"retain\": \"1\", \"room\": \"HaBridge,Arbeitszimmer,mqtt\", \"stateFormat\": \"state\", \"subscribeReading_state\": \"/SmartHome/az/stecker/stat/POWER\", \"webCmd\": \"on:off:toggle\" } } ], \"totalResultsReturned\":1 }" +
|
||||
" </pre>\n" +
|
||||
" </div>\n" +
|
||||
" </body>\n" +
|
||||
"</html>";
|
||||
public final static String TestData3 ="DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n" +
|
||||
"<html xmlns=\"http://www.w3.org/1999/xhtml\">\n" +
|
||||
"<head root=\"/fhem\">\n" +
|
||||
"<title>Home, Sweet Home</title>\n" +
|
||||
"<link rel=\"shortcut icon\" href=\"/fhem/icons/favicon\" />\n" +
|
||||
"<meta charset=\"UTF-8\">\n" +
|
||||
"<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n" +
|
||||
"<link href=\"/fhem/pgm2/style.css?v=1515015198\" rel=\"stylesheet\"/>\n" +
|
||||
"<link href=\"/fhem/pgm2/jquery-ui.min.css\" rel=\"stylesheet\"/>\n" +
|
||||
"<script attr='' type=\"text/javascript\" src=\"/fhem/pgm2/jquery.min.js\"></script>\n" +
|
||||
"<script attr='' type=\"text/javascript\" src=\"/fhem/pgm2/jquery-ui.min.js\"></script>\n" +
|
||||
"<script attr='' type=\"text/javascript\" src=\"/fhem/pgm2/fhemweb.js\"></script>\n" +
|
||||
"<script attr='' type=\"text/javascript\" src=\"/fhem/pgm2/doif.js\"></script>\n" +
|
||||
"<script attr='' type=\"text/javascript\" src=\"/fhem/pgm2/fronthemEditor.js\"></script>\n" +
|
||||
"<script attr='' type=\"text/javascript\" src=\"/fhem/pgm2/fhemweb_readingsGroup.js\"></script>\n" +
|
||||
"</head>\n" +
|
||||
"<body name='Home, Sweet Home' fw_id='1490' generated=\"1515770038\" longpoll=\"websocket\" data-confirmDelete='1' data-confirmJSError='1' data-addHtmlTitle='1' data-availableJs='sortable,iconLabel,readingsHistory,colorpicker,iconButtons,fbcalllist,knob,weekprofile,iconRadio,readingsGroup,iconSwitch,uzsu' data-webName='WEB '>\n" +
|
||||
"<div id=\"menuScrollArea\">\n" +
|
||||
"</div>\n" +
|
||||
"<div id='content' >\n" +
|
||||
"<pre>{\n" +
|
||||
"\"Arg\":\"room=HaBridge\",\n" +
|
||||
"\"Results\": [\n" +
|
||||
"{\n" +
|
||||
"\"Name\":\"<a href='/fhem?detail=wifi_steckdose3'>wifi_steckdose3</a>\",\n" +
|
||||
"\"PossibleSets\":\"on:noArg off:noArg off on toggle\",\n" +
|
||||
"\"PossibleAttrs\":\"alias comment:textField-long eventMap group room suppressReading userReadings:textField-long verbose:0,1,2,3,4,5 IODev qos retain publishSet publishSet_.* subscribeReading_.* autoSubscribeReadings event-on-change-reading event-on-update-reading event-aggregator event-min-interval stateFormat:textField-long timestamp-on-change-reading alarmDevice:Actor,Sensor alarmSettings cmdIcon devStateIcon devStateStyle icon lightSceneParamsToSave lightSceneRestoreOnlyIfChanged:1,0 sortby structexclude webCmd webCmdLabel:textField-long widgetOverride userattr\",\n" +
|
||||
"\"Internals\": {\n" +
|
||||
"\"NAME\": \"<a href='/fhem?detail=wifi_steckdose3'>wifi_steckdose3</a>\",\n" +
|
||||
"\"NR\": \"270\",\n" +
|
||||
"\"STATE\": \"off\",\n" +
|
||||
"\"TYPE\": \"MQTT_DEVICE\",\n" +
|
||||
"\"retain\": \"*:1 \"\n" +
|
||||
"},\n" +
|
||||
"\"Readings\": {\n" +
|
||||
"\"state\": { \"Value\":\"OFF\", \"Time\":\"2018-01-07 05:16:01\" },\n" +
|
||||
"\"transmission-state\": { \"Value\":\"incoming publish received\", \"Time\":\"2018-01-07 05:16:01\" }\n" +
|
||||
"},\n" +
|
||||
"\"Attributes\": {\n" +
|
||||
"\"IODev\": \"<a href='/fhem?detail=myBroker'>myBroker</a>\",\n" +
|
||||
"\"alias\": \"Stecki\",\n" +
|
||||
"\"devStateIcon\": \"on:black_Steckdose.on off:black_Steckdose.off\",\n" +
|
||||
"\"event-on-change-reading\": \"state\",\n" +
|
||||
"\"eventMap\": \"ON:on OFF:off\",\n" +
|
||||
"\"publishSet\": \"on off toggle /SmartHome/az/stecker/cmnd/POWER\",\n" +
|
||||
"\"retain\": \"1\",\n" +
|
||||
"\"room\": \"HaBridge,Arbeitszimmer,mqtt\",\n" +
|
||||
"\"stateFormat\": \"state\",\n" +
|
||||
"\"subscribeReading_state\": \"/SmartHome/az/stecker/stat/POWER\",\n" +
|
||||
"\"webCmd\": \"on:off:toggle\"\n" +
|
||||
"}\n" +
|
||||
"} ],\n" +
|
||||
"\"totalResultsReturned\":1\n" +
|
||||
"}\n" +
|
||||
"</pre>\n" +
|
||||
"</div>\n" +
|
||||
"</body></html>";
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
|
||||
package com.bwssystems.HABridge.plugins.fhem;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class Result {
|
||||
|
||||
@SerializedName("Name")
|
||||
@Expose
|
||||
private String name;
|
||||
@SerializedName("PossibleSets")
|
||||
@Expose
|
||||
private String possibleSets;
|
||||
@SerializedName("PossibleAttrs")
|
||||
@Expose
|
||||
private String possibleAttrs;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getPossibleSets() {
|
||||
return possibleSets;
|
||||
}
|
||||
|
||||
public void setPossibleSets(String possibleSets) {
|
||||
this.possibleSets = possibleSets;
|
||||
}
|
||||
|
||||
public String getPossibleAttrs() {
|
||||
return possibleAttrs;
|
||||
}
|
||||
|
||||
public void setPossibleAttrs(String possibleAttrs) {
|
||||
this.possibleAttrs = possibleAttrs;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.bwssystems.HABridge.plugins.fibaro;
|
||||
|
||||
public class FibaroFilter {
|
||||
boolean useSaveLogs;
|
||||
boolean useUserDescription;
|
||||
boolean scenesLiliCmddOnly;
|
||||
boolean replaceTrash;
|
||||
|
||||
public boolean isUseSaveLogs() {
|
||||
return useSaveLogs;
|
||||
}
|
||||
public void setUseSaveLogs(boolean useSaveLogs) {
|
||||
this.useSaveLogs = useSaveLogs;
|
||||
}
|
||||
public boolean isUseUserDescription() {
|
||||
return useUserDescription;
|
||||
}
|
||||
public void setUseUserDescription(boolean useUserDescription) {
|
||||
this.useUserDescription = useUserDescription;
|
||||
}
|
||||
public boolean isReplaceTrash() {
|
||||
return replaceTrash;
|
||||
}
|
||||
public void setReplaceTrash(boolean replaceTrash) {
|
||||
this.replaceTrash = replaceTrash;
|
||||
}
|
||||
public boolean isScenesLiliCmddOnly() {
|
||||
return scenesLiliCmddOnly;
|
||||
}
|
||||
public void setScenesLiliCmddOnly(boolean scenesLiliCmddOnly) {
|
||||
this.scenesLiliCmddOnly = scenesLiliCmddOnly;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -84,6 +84,11 @@ public class FibaroHome implements Home
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh() {
|
||||
// noop
|
||||
}
|
||||
|
||||
@Override
|
||||
public Home createHome(BridgeSettings bridgeSettings)
|
||||
{
|
||||
|
||||
@@ -6,7 +6,6 @@ import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -23,19 +22,33 @@ public class FibaroInfo
|
||||
private final NamedIP fibaroAddress;
|
||||
private final String fibaroAuth;
|
||||
private final Gson gson;
|
||||
|
||||
// You can disable it if you want TODO config
|
||||
boolean useSaveLogs = true; // This can be used to exclude some devices from list
|
||||
boolean useUserDescription = true;
|
||||
boolean replaceTrash = true;
|
||||
boolean scenesWithLiliCommandOnly = true;
|
||||
private Boolean isDevMode;
|
||||
private FibaroFilter theFilters;
|
||||
|
||||
public FibaroInfo(NamedIP addressName)
|
||||
{
|
||||
super();
|
||||
fibaroAddress = addressName;
|
||||
fibaroAuth = "Basic " + new String(Base64.encodeBase64((addressName.getUsername() + ":" + addressName.getPassword()).getBytes()));
|
||||
fibaroAuth = "Basic " + addressName.getUserPass64();
|
||||
isDevMode = Boolean.parseBoolean(System.getProperty("dev.mode", "false"));
|
||||
gson = new Gson();
|
||||
theFilters = null;
|
||||
if(fibaroAddress.getExtensions() != null) {
|
||||
try {
|
||||
theFilters = gson.fromJson(fibaroAddress.getExtensions(), FibaroFilter.class);
|
||||
} catch(Exception e) {
|
||||
log.warn("Could not read fibaro filters - continuing with defaults.");
|
||||
theFilters = null;
|
||||
}
|
||||
}
|
||||
|
||||
if(theFilters == null) {
|
||||
theFilters = new FibaroFilter();
|
||||
theFilters.setUseSaveLogs(false);
|
||||
theFilters.setUseUserDescription(false);
|
||||
theFilters.setScenesLiliCmddOnly(false);
|
||||
theFilters.setReplaceTrash(true);
|
||||
}
|
||||
}
|
||||
|
||||
private String request(String request)
|
||||
@@ -66,24 +79,6 @@ public class FibaroInfo
|
||||
return result;
|
||||
}
|
||||
|
||||
protected boolean sendCommand(String request)
|
||||
{
|
||||
try
|
||||
{
|
||||
URL url = new URL("http://" + fibaroAddress.getIp() + ":" + fibaroAddress.getPort() + request);
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod("GET");
|
||||
connection.setRequestProperty("Authorization", fibaroAuth);
|
||||
connection.getResponseMessage();
|
||||
}
|
||||
catch(IOException e)
|
||||
{
|
||||
log.warn("Error while get getJson: {} ", request, e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private String replaceTrash(String name)
|
||||
{
|
||||
String sanitizedName = name.replaceAll("[0-9:/-]", "");
|
||||
@@ -93,9 +88,14 @@ public class FibaroInfo
|
||||
|
||||
private Room[] getRooms()
|
||||
{
|
||||
String result = request("/api/rooms");
|
||||
String result = null;
|
||||
if(isDevMode)
|
||||
result = FibaroTestData.RoomTestData;
|
||||
else
|
||||
result = request("/api/rooms");
|
||||
log.debug("getRooms response: <<<" + result + ">>>");
|
||||
Room[] rooms = result == null ? new Room[0] : gson.fromJson(result, Room[].class);
|
||||
if(replaceTrash)
|
||||
if(theFilters.isReplaceTrash())
|
||||
for(Room r : rooms)
|
||||
r.setName(replaceTrash(r.getName()));
|
||||
return rooms;
|
||||
@@ -105,24 +105,29 @@ public class FibaroInfo
|
||||
{
|
||||
Room[] rooms = getRooms();
|
||||
|
||||
log.info("Found: " + rooms.length + " rooms");
|
||||
log.debug("getDevices Found: " + rooms.length + " rooms");
|
||||
|
||||
String result = request("/api/devices?enabled=true&visible=true");
|
||||
String result = null;
|
||||
if(isDevMode)
|
||||
result = FibaroTestData.DeviceTestData;
|
||||
else
|
||||
result = request("/api/devices?enabled=true&visible=true");
|
||||
log.debug("getDevices response: <<<" + result + ">>>");
|
||||
Device[] all_devices = result == null ? new Device[0] : gson.fromJson(result, Device[].class);
|
||||
|
||||
int count = 0;
|
||||
for(Device d : all_devices)
|
||||
if(d.getRoomID() > 0 && (useSaveLogs ? "true".equals(d.getProperties().getSaveLogs()) : true))
|
||||
if(d.getRoomID() > 0 && (theFilters.isUseSaveLogs() ? "true".equals(d.getProperties().getSaveLogs()) : true))
|
||||
count++;
|
||||
|
||||
Device[] devices = new Device[count];
|
||||
int i = 0;
|
||||
for(Device d : all_devices)
|
||||
if(d.getRoomID() > 0 && (useSaveLogs ? "true".equals(d.getProperties().getSaveLogs()) : true))
|
||||
if(d.getRoomID() > 0 && (theFilters.isUseSaveLogs() ? "true".equals(d.getProperties().getSaveLogs()) : true))
|
||||
{
|
||||
if(useUserDescription && d.getProperties().getUserDescription() != null && !d.getProperties().getUserDescription().isEmpty())
|
||||
if(theFilters.isUseUserDescription() && d.getProperties().getUserDescription() != null && !d.getProperties().getUserDescription().isEmpty())
|
||||
d.setName(d.getProperties().getUserDescription());
|
||||
if(replaceTrash)
|
||||
if(theFilters.isReplaceTrash())
|
||||
d.setName(replaceTrash(d.getName()));
|
||||
|
||||
devices[i++] = d;
|
||||
@@ -137,7 +142,7 @@ public class FibaroInfo
|
||||
d.fibaroname = fibaroAddress.getName();
|
||||
}
|
||||
|
||||
log.info("Found: " + devices.length + " devices");
|
||||
log.debug("getDevices Found: " + devices.length + " devices");
|
||||
|
||||
return devices;
|
||||
}
|
||||
@@ -146,19 +151,24 @@ public class FibaroInfo
|
||||
{
|
||||
Room[] rooms = getRooms();
|
||||
|
||||
String result = request("/api/scenes?enabled=true&visible=true");
|
||||
String result = null;
|
||||
if(isDevMode)
|
||||
result = FibaroTestData.SceneTestData;
|
||||
else
|
||||
result = request("/api/scenes?enabled=true&visible=true");
|
||||
log.debug("getScenes response: <<<" + result + ">>>");
|
||||
Scene[] all_scenes = result == null ? new Scene[0] : gson.fromJson(result, Scene[].class);
|
||||
|
||||
int count = 0;
|
||||
for(Scene s : all_scenes)
|
||||
if(!scenesWithLiliCommandOnly || s.getLiliStartCommand() != null && !s.getLiliStartCommand().isEmpty())
|
||||
if(!theFilters.isScenesLiliCmddOnly() || s.getLiliStartCommand() != null && !s.getLiliStartCommand().isEmpty())
|
||||
count++;
|
||||
Scene[] scenes = new Scene[count];
|
||||
int i = 0;
|
||||
for(Scene s : all_scenes)
|
||||
if(!scenesWithLiliCommandOnly || s.getLiliStartCommand() != null && !s.getLiliStartCommand().isEmpty())
|
||||
if(!theFilters.isScenesLiliCmddOnly() || s.getLiliStartCommand() != null && !s.getLiliStartCommand().isEmpty())
|
||||
{
|
||||
if(replaceTrash)
|
||||
if(theFilters.isReplaceTrash())
|
||||
s.setName(replaceTrash(s.getName()));
|
||||
|
||||
scenes[i++] = s;
|
||||
@@ -172,7 +182,7 @@ public class FibaroInfo
|
||||
s.fibaroAuth = fibaroAuth;
|
||||
s.fibaroname = fibaroAddress.getName();
|
||||
}
|
||||
log.info("Found: " + count + " scenes");
|
||||
log.debug("getScenes Found: " + count + " scenes");
|
||||
return scenes;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.bwssystems.HABridge.plugins.fibaro;
|
||||
|
||||
public class FibaroTestData {
|
||||
public final static String DeviceTestData = "[{\"id\":7,\"name\":\"Deckenspots\",\"roomID\":12,\"type\":\"com.fibaro.FGD212\",\"baseType\":\"com.fibaro.multilevelSwitch\",\"enabled\":true,\"visible\":true,\"isPlugin\":false,\"parentId\":5,\"remoteGatewayId\":0,\"viewXml\":false,\"configXml\":false,\"interfaces\":[\"deviceGrouping\",\"energy\",\"levelChange\",\"light\",\"power\",\"zwave\",\"zwaveAlarm\",\"zwaveMultiChannelAssociation\",\"zwaveProtection\",\"zwaveSceneActivation\"],\"properties\":{\"pollingTimeSec\":0,\"zwaveCompany\":\"Fibargroup\",\"zwaveInfo\":\"3,4,5\",\"zwaveVersion\":\"3.5\",\"RFProtectionState\":\"0\",\"RFProtectionSupport\":\"3\",\"alarmLevel\":\"0\",\"alarmType\":\"0\",\"configured\":true,\"dead\":\"false\",\"deviceControlType\":\"23\",\"deviceGroup\":\"[]\",\"deviceGroupMaster\":\"0\",\"deviceIcon\":\"15\",\"emailNotificationID\":\"0\",\"emailNotificationType\":\"0\",\"endPointId\":\"1\",\"energy\":\"7.23\",\"isLight\":\"true\",\"liliOffCommand\":\"\",\"liliOnCommand\":\"\",\"localProtectionState\":\"0\",\"localProtectionSupport\":\"5\",\"log\":\"\",\"logTemp\":\"\",\"manufacturer\":\"\",\"markAsDead\":\"true\",\"model\":\"\",\"nodeId\":\"2\",\"parametersTemplate\":\"796\",\"power\":\"5.80\",\"productInfo\":\"1,15,1,2,16,0,3,5\",\"protectionExclusiveControl\":\"0\",\"protectionExclusiveControlSupport\":\"false\",\"protectionState\":\"0\",\"protectionTimeout\":\"0\",\"protectionTimeoutSupport\":\"false\",\"pushNotificationID\":\"0\",\"pushNotificationType\":\"0\",\"remoteGatewayId\":\"0\",\"saveLogs\":\"true\",\"sceneActivation\":\"25\",\"serialNumber\":\"h'000000000001c1b4\",\"showEnergy\":\"true\",\"smsNotificationID\":\"0\",\"smsNotificationType\":\"0\",\"useTemplate\":\"true\",\"userDescription\":\"\",\"value\":\"5\"},\"actions\":{\"reconfigure\":0,\"reset\":0,\"sceneActivationSet\":0,\"setValue\":1,\"startLevelDecrease\":0,\"startLevelIncrease\":0,\"stopLevelChange\":0,\"turnOff\":0,\"turnOn\":0},\"created\":1516643104,\"modified\":1516643104,\"sortOrder\":1},{\"id\":13,\"name\":\"Licht Küche\",\"roomID\":13,\"type\":\"com.fibaro.binarySwitch\",\"baseType\":\"com.fibaro.actor\",\"enabled\":true,\"visible\":true,\"isPlugin\":false,\"parentId\":10,\"remoteGatewayId\":0,\"viewXml\":false,\"configXml\":fals" +
|
||||
"e,\"interfaces\":[\"deviceGrouping\",\"energy\",\"light\",\"power\",\"zwave\",\"zwaveMultiChannelAssociation\",\"zwaveProtection\"],\"properties\":{\"pollingTimeSec\":0,\"zwaveCompany\":\"Fibargroup\",\"zwaveInfo\":\"3,4,5\",\"zwaveVersion\":\"3.2\",\"RFProtectionState\":\"0\",\"RFProtectionSupport\":\"3\",\"configured\":true,\"dead\":\"false\",\"deviceControlType\":\"2\",\"deviceGroup\":\"[]\",\"deviceGroupMaster\":\"0\",\"deviceIcon\":\"2\",\"emailNotificationID\":\"0\",\"emailNotificationType\":\"0\",\"endPointId\":\"1\",\"energy\":\"9.51\",\"isLight\":\"true\",\"liliOffCommand\":\"\",\"liliOnCommand\":\"\",\"localProtectionState\":\"0\",\"localProtectionSupport\":\"5\",\"log\":\"\",\"logTemp\":\"\",\"manufacturer\":\"\",\"markAsDead\":\"true\",\"model\":\"\",\"nodeId\":\"3\",\"parametersTemplate\":\"781\",\"power\":\"16.00\",\"productInfo\":\"1,15,2,3,16,0,3,2\",\"protectionExclusiveControl\":\"0\",\"protectionExclusiveControlSupport\":\"false\",\"protectionState\":\"0\",\"protectionTimeout\":\"0\",\"protectionTimeoutSupport\":\"false\",\"pushNotificationID\":\"0\",\"pushNotificationType\":\"0\",\"remoteGatewayId\":\"0\",\"saveLogs\":\"true\",\"serialNumber\":\"h'000000000000450d\",\"showEnergy\":\"true\",\"smsNotificationID\":\"0\",\"smsNotificationType\":\"0\",\"useTemplate\":\"true\",\"userDescription\":\"\",\"value\":\"true\"},\"actions\":{\"reconfigure\":0,\"reset\":0,\"turnOff\":0,\"turnOn\":0},\"created\":1516643104,\"modified\":1516643104,\"sortOrder\":2},{\"id\":14,\"name\":\"Lampe Tisch\",\"roomID\":14,\"type\":\"com.fibaro.binarySwitch\",\"baseType\":\"com.fibaro.actor\",\"enabled\":true,\"visible\":true,\"isPlugin\":false,\"parentId\":10,\"remoteGatewayId\":0,\"viewXml\":false,\"configXml\":false,\"interfaces\":[\"deviceGrouping\",\"energy\",\"light\",\"power\",\"zwave\",\"zwaveMultiChannelAssociation\",\"zwaveProtection\"],\"properties\":{\"pollingTimeSec\":0,\"zwaveCompany\":\"Fibargroup\",\"zwaveInfo\":\"3,4,5\",\"zwaveVersion\":\"3.2\",\"RFProtectionState\":\"0\",\"RFProtectionSupport\":\"3\",\"configured\":true,\"dead\":\"false\",\"deviceControlType\":\"2\",\"deviceGroup\":\"[]\",\"deviceGroupMaster\":\"0\",\"deviceIcon\":\"2\",\"emailNotificationID\":\"0\",\"emailNotificationType\":\"0\",\"endPointId\":\"2\",\"energy\":\"29.15\",\"isLight\":\"true\",\"liliOffCommand\":\"\",\"liliOnCommand\":\"\",\"localProtectionState\":" +
|
||||
"\"0\",\"localProtectionSupport\":\"5\",\"log\":\"\",\"logTemp\":\"\",\"manufacturer\":\"\",\"markAsDead\":\"true\",\"model\":\"\",\"nodeId\":\"3\",\"parametersTemplate\":\"781\",\"power\":\"11.50\",\"productInfo\":\"1,15,2,3,16,0,3,2\",\"protectionExclusiveControl\":\"0\",\"protectionExclusiveControlSupport\":\"false\",\"protectionState\":\"0\",\"protectionTimeout\":\"0\",\"protectionTimeoutSupport\":\"false\",\"pushNotificationID\":\"0\",\"pushNotificationType\":\"0\",\"remoteGatewayId\":\"0\",\"saveLogs\":\"true\",\"serialNumber\":\"h'000000000000450d\",\"showEnergy\":\"true\",\"smsNotificationID\":\"0\",\"smsNotificationType\":\"0\",\"useTemplate\":\"true\",\"userDescription\":\"\",\"value\":\"true\"},\"actions\":{\"reconfigure\":0,\"reset\":0,\"turnOff\":0,\"turnOn\":0},\"created\":1516643104,\"modified\":1516643104,\"sortOrder\":3},{\"id\":18,\"name\":\"Licht\",\"roomID\":16,\"type\":\"com.fibaro.binarySwitch\",\"baseType\":\"com.fibaro.actor\",\"enabled\":true,\"visible\":true,\"isPlugin\":false,\"parentId\":15,\"remoteGatewayId\":0,\"viewXml\":false,\"configXml\":false,\"interfaces\":[\"deviceGrouping\",\"energy\",\"light\",\"power\",\"zwave\",\"zwaveMultiChannelAssociation\",\"zwaveProtection\"],\"properties\":{\"pollingTimeSec\":0,\"zwaveCompany\":\"Fibargroup\",\"zwaveInfo\":\"3,4,5\",\"zwaveVersion\":\"3.2\",\"RFProtectionState\":\"0\",\"RFProtectionSupport\":\"3\",\"configured\":true,\"dead\":\"false\",\"deviceControlType\":\"2\",\"deviceGroup\":\"[]\",\"deviceGroupMaster\":\"0\",\"deviceIcon\":\"2\",\"emailNotificationID\":\"0\",\"emailNotificationType\":\"0\",\"endPointId\":\"1\",\"energy\":\"2.70\",\"isLight\":\"true\",\"liliOffCommand\":\"\",\"liliOnCommand\":\"\",\"localProtectionState\":\"0\",\"localProtectionSupport\":\"5\",\"log\":\"\",\"logTemp\":\"\",\"manufacturer\":\"\",\"markAsDead\":\"true\",\"model\":\"\",\"nodeId\":\"4\",\"parametersTemplate\":\"781\",\"power\":\"0.00\",\"productInfo\":\"1,15,2,3,16,0,3,2\",\"protectionExclusiveControl\":\"0\",\"protectionExclusiveControlSupport\":\"false\",\"protectionState\":\"0\",\"protectionTimeout\":\"0\",\"protectionTimeoutSupport\":\"false\",\"pushNotificationID\":\"0\",\"pushNotificationType\":\"0\",\"remoteGatewayId\":\"0\",\"saveLogs\":\"true\",\"serialNumber\":\"h'00000000000044b4\",\"showEnergy\":\"true\",\"smsNotificationID\":\"0\",\"smsNotificationType\":\"0\",\"useTempl" +
|
||||
"ate\":\"true\",\"userDescription\":\"\",\"value\":\"false\"},\"actions\":{\"reconfigure\":0,\"reset\":0,\"turnOff\":0,\"turnOn\":0},\"created\":1516643104,\"modified\":1516643104,\"sortOrder\":4},{\"id\":26,\"name\":\"Licht\",\"roomID\":5,\"type\":\"com.fibaro.FGD212\",\"baseType\":\"com.fibaro.multilevelSwitch\",\"enabled\":true,\"visible\":true,\"isPlugin\":false,\"parentId\":24,\"remoteGatewayId\":0,\"viewXml\":false,\"configXml\":false,\"interfaces\":[\"deviceGrouping\",\"energy\",\"levelChange\",\"light\",\"power\",\"zwave\",\"zwaveAlarm\",\"zwaveMultiChannelAssociation\",\"zwaveProtection\",\"zwaveSceneActivation\"],\"properties\":{\"pollingTimeSec\":0,\"zwaveCompany\":\"Fibargroup\",\"zwaveInfo\":\"3,4,5\",\"zwaveVersion\":\"3.5\",\"RFProtectionState\":\"0\",\"RFProtectionSupport\":\"3\",\"alarmLevel\":\"0\",\"alarmType\":\"0\",\"configured\":true,\"dead\":\"false\",\"deviceControlType\":\"23\",\"deviceGroup\":\"[]\",\"deviceGroupMaster\":\"0\",\"deviceIcon\":\"15\",\"emailNotificationID\":\"0\",\"emailNotificationType\":\"0\",\"endPointId\":\"1\",\"energy\":\"28.02\",\"isLight\":\"true\",\"liliOffCommand\":\"\",\"liliOnCommand\":\"\",\"localProtectionState\":\"0\",\"localProtectionSupport\":\"5\",\"log\":\"\",\"logTemp\":\"\",\"manufacturer\":\"\",\"markAsDead\":\"true\",\"model\":\"\",\"nodeId\":\"7\",\"parametersTemplate\":\"796\",\"power\":\"0.00\",\"productInfo\":\"1,15,1,2,16,0,3,5\",\"protectionExclusiveControl\":\"0\",\"protectionExclusiveControlSupport\":\"false\",\"protectionState\":\"0\",\"protectionTimeout\":\"0\",\"protectionTimeoutSupport\":\"false\",\"pushNotificationID\":\"0\",\"pushNotificationType\":\"0\",\"remoteGatewayId\":\"0\",\"saveLogs\":\"true\",\"sceneActivation\":\"0\",\"serialNumber\":\"h'0000000000001fec\",\"showEnergy\":\"true\",\"smsNotificationID\":\"0\",\"smsNotificationType\":\"0\",\"useTemplate\":\"true\",\"userDescription\":\"\",\"value\":\"0\"},\"actions\":{\"reconfigure\":0,\"reset\":0,\"sceneActivationSet\":0,\"setValue\":1,\"startLevelDecrease\":0,\"startLevelIncrease\":0,\"stopLevelChange\":0,\"turnOff\":0,\"turnOn\":0},\"created\":1516643105,\"modified\":1516643105,\"sortOrder\":5},{\"id\":57,\"name\":\"Fenster rechts\",\"roomID\":14,\"type\":\"com.fibaro.FGRM222\",\"baseType\":\"com.fibaro.FGR\",\"enabled\":true,\"visible\":true,\"isPlugin\":false,\"parentId\":56,\"remoteGatewayId\"" +
|
||||
":0,\"viewXml\":false,\"configXml\":false,\"interfaces\":[\"energy\",\"levelChange\",\"power\",\"zwave\",\"zwaveMultiChannelAssociation\",\"zwaveProtection\",\"zwaveSceneActivation\"],\"properties\":{\"pollingTimeSec\":0,\"zwaveCompany\":\"Fibargroup\",\"zwaveInfo\":\"3,3,52\",\"zwaveVersion\":\"25.25\",\"RFProtectionState\":\"0\",\"RFProtectionSupport\":\"3\",\"configured\":true,\"dead\":\"false\",\"deviceControlType\":\"54\",\"deviceIcon\":\"87\",\"emailNotificationID\":\"0\",\"emailNotificationType\":\"0\",\"endPointId\":\"0\",\"energy\":\"0.78\",\"liliOffCommand\":\"\",\"liliOnCommand\":\"\",\"localProtectionState\":\"0\",\"localProtectionSupport\":\"5\",\"log\":\"\",\"logTemp\":\"\",\"manufacturer\":\"\",\"markAsDead\":\"true\",\"model\":\"\",\"nodeId\":\"19\",\"parametersTemplate\":\"721\",\"power\":\"0.00\",\"productInfo\":\"1,15,3,2,16,0,25,25\",\"protectionExclusiveControl\":\"0\",\"protectionExclusiveControlSupport\":\"false\",\"protectionLocal\":\"0\",\"protectionLocalSupport\":\"5\",\"protectionRF\":\"0\",\"protectionRFSupport\":\"3\",\"protectionState\":\"0\",\"protectionTimeout\":\"0\",\"protectionTimeoutSupport\":\"false\",\"pushNotificationID\":\"0\",\"pushNotificationType\":\"0\",\"remoteGatewayId\":\"0\",\"saveLogs\":\"true\",\"sceneActivation\":\"0\",\"serialNumber\":\"\",\"showEnergy\":\"true\",\"smsNotificationID\":\"0\",\"smsNotificationType\":\"0\",\"useTemplate\":\"true\",\"userDescription\":\"\",\"value\":\"0\",\"value2\":\"0\"},\"actions\":{\"close\":0,\"open\":0,\"reconfigure\":0,\"reset\":0,\"sceneActivationSet\":0,\"setValue\":1,\"setValue2\":1,\"startLevelDecrease\":0,\"startLevelIncrease\":0,\"stop\":0,\"stopLevelChange\":0},\"created\":1516643105,\"modified\":1516643105,\"sortOrder\":12},{\"id\":60,\"name\":\"Fenster mitte\",\"roomID\":14,\"type\":\"com.fibaro.FGRM222\",\"baseType\":\"com.fibaro.FGR\",\"enabled\":true,\"visible\":true,\"isPlugin\":false,\"parentId\":59,\"remoteGatewayId\":0,\"viewXml\":false,\"configXml\":false,\"interfaces\":[\"energy\",\"levelChange\",\"power\",\"zwave\",\"zwaveMultiChannelAssociation\",\"zwaveProtection\",\"zwaveSceneActivation\"],\"properties\":{\"pollingTimeSec\":0,\"zwaveCompany\":\"Fibargroup\",\"zwaveInfo\":\"3,3,52\",\"zwaveVersion\":\"25.25\",\"RFProtectionState\":\"0\",\"RFProtectionSupport\":\"3\",\"configured\":true,\"dead\":\"false\",\"deviceControlT" +
|
||||
"ype\":\"54\",\"deviceIcon\":\"87\",\"emailNotificationID\":\"0\",\"emailNotificationType\":\"0\",\"endPointId\":\"0\",\"energy\":\"0.71\",\"liliOffCommand\":\"\",\"liliOnCommand\":\"\",\"localProtectionState\":\"0\",\"localProtectionSupport\":\"5\",\"log\":\"\",\"logTemp\":\"\",\"manufacturer\":\"\",\"markAsDead\":\"true\",\"model\":\"\",\"nodeId\":\"20\",\"parametersTemplate\":\"721\",\"power\":\"0.00\",\"productInfo\":\"1,15,3,2,16,0,25,25\",\"protectionExclusiveControl\":\"0\",\"protectionExclusiveControlSupport\":\"false\",\"protectionLocal\":\"0\",\"protectionLocalSupport\":\"5\",\"protectionRF\":\"0\",\"protectionRFSupport\":\"3\",\"protectionState\":\"0\",\"protectionTimeout\":\"0\",\"protectionTimeoutSupport\":\"false\",\"pushNotificationID\":\"0\",\"pushNotificationType\":\"0\",\"remoteGatewayId\":\"0\",\"saveLogs\":\"true\",\"sceneActivation\":\"26\",\"serialNumber\":\"\",\"showEnergy\":\"true\",\"smsNotificationID\":\"0\",\"smsNotificationType\":\"0\",\"useTemplate\":\"true\",\"userDescription\":\"\",\"value\":\"0\",\"value2\":\"0\"},\"actions\":{\"close\":0,\"open\":0,\"reconfigure\":0,\"reset\":0,\"sceneActivationSet\":0,\"setValue\":1,\"setValue2\":1,\"startLevelDecrease\":0,\"startLevelIncrease\":0,\"stop\":0,\"stopLevelChange\":0},\"created\":1516643105,\"modified\":1516643105,\"sortOrder\":13},{\"id\":74,\"name\":\"Fenster links\",\"roomID\":14,\"type\":\"com.fibaro.FGRM222\",\"baseType\":\"com.fibaro.FGR\",\"enabled\":true,\"visible\":true,\"isPlugin\":false,\"parentId\":73,\"remoteGatewayId\":0,\"viewXml\":false,\"configXml\":false,\"interfaces\":[\"energy\",\"levelChange\",\"power\",\"zwave\",\"zwaveMultiChannelAssociation\",\"zwaveProtection\",\"zwaveSceneActivation\"],\"properties\":{\"pollingTimeSec\":0,\"zwaveCompany\":\"Fibargroup\",\"zwaveInfo\":\"3,3,52\",\"zwaveVersion\":\"25.25\",\"RFProtectionState\":\"0\",\"RFProtectionSupport\":\"3\",\"configured\":true,\"dead\":\"false\",\"deviceControlType\":\"54\",\"deviceIcon\":\"87\",\"emailNotificationID\":\"0\",\"emailNotificationType\":\"0\",\"endPointId\":\"0\",\"energy\":\"0.64\",\"liliOffCommand\":\"\",\"liliOnCommand\":\"\",\"localProtectionState\":\"0\",\"localProtectionSupport\":\"5\",\"log\":\"\",\"logTemp\":\"\",\"manufacturer\":\"\",\"markAsDead\":\"true\",\"model\":\"\",\"nodeId\":\"21\",\"parametersTemplate\":\"721\",\"power\":\"0.00\",\"productInfo\":\"1,15,3,2,16,0" +
|
||||
",25,25\",\"protectionExclusiveControl\":\"0\",\"protectionExclusiveControlSupport\":\"false\",\"protectionLocal\":\"0\",\"protectionLocalSupport\":\"5\",\"protectionRF\":\"0\",\"protectionRFSupport\":\"3\",\"protectionState\":\"0\",\"protectionTimeout\":\"0\",\"protectionTimeoutSupport\":\"false\",\"pushNotificationID\":\"0\",\"pushNotificationType\":\"0\",\"remoteGatewayId\":\"0\",\"saveLogs\":\"true\",\"sceneActivation\":\"0\",\"serialNumber\":\"\",\"showEnergy\":\"true\",\"smsNotificationID\":\"0\",\"smsNotificationType\":\"0\",\"useTemplate\":\"true\",\"userDescription\":\"\",\"value\":\"0\",\"value2\":\"0\"},\"actions\":{\"close\":0,\"open\":0,\"reconfigure\":0,\"reset\":0,\"sceneActivationSet\":0,\"setValue\":1,\"setValue2\":1,\"startLevelDecrease\":0,\"startLevelIncrease\":0,\"stop\":0,\"stopLevelChange\":0},\"created\":1516643106,\"modified\":1516643106,\"sortOrder\":14},{\"id\":77,\"name\":\"Fenster Sideboard\",\"roomID\":14,\"type\":\"com.fibaro.FGRM222\",\"baseType\":\"com.fibaro.FGR\",\"enabled\":true,\"visible\":true,\"isPlugin\":false,\"parentId\":76,\"remoteGatewayId\":0,\"viewXml\":false,\"configXml\":false,\"interfaces\":[\"energy\",\"levelChange\",\"power\",\"zwave\",\"zwaveMultiChannelAssociation\",\"zwaveProtection\",\"zwaveSceneActivation\"],\"properties\":{\"pollingTimeSec\":0,\"zwaveCompany\":\"Fibargroup\",\"zwaveInfo\":\"3,3,52\",\"zwaveVersion\":\"25.25\",\"RFProtectionState\":\"0\",\"RFProtectionSupport\":\"3\",\"configured\":true,\"dead\":\"false\",\"deviceControlType\":\"54\",\"deviceIcon\":\"87\",\"emailNotificationID\":\"0\",\"emailNotificationType\":\"0\",\"endPointId\":\"0\",\"energy\":\"0.63\",\"liliOffCommand\":\"\",\"liliOnCommand\":\"\",\"localProtectionState\":\"0\",\"localProtectionSupport\":\"5\",\"log\":\"\",\"logTemp\":\"\",\"manufacturer\":\"\",\"markAsDead\":\"true\",\"model\":\"\",\"nodeId\":\"22\",\"parametersTemplate\":\"721\",\"power\":\"0.00\",\"productInfo\":\"1,15,3,2,16,0,25,25\",\"protectionExclusiveControl\":\"0\",\"protectionExclusiveControlSupport\":\"false\",\"protectionLocal\":\"0\",\"protectionLocalSupport\":\"5\",\"protectionRF\":\"0\",\"protectionRFSupport\":\"3\",\"protectionState\":\"0\",\"protectionTimeout\":\"0\",\"protectionTimeoutSupport\":\"false\",\"pushNotificationID\":\"0\",\"pushNotificationType\":\"0\",\"remoteGatewayId\":\"0\",\"saveLogs\":\"true\",\"sceneAc" +
|
||||
"tivation\":\"0\",\"serialNumber\":\"\",\"showEnergy\":\"true\",\"smsNotificationID\":\"0\",\"smsNotificationType\":\"0\",\"useTemplate\":\"true\",\"userDescription\":\"\",\"value\":\"0\",\"value2\":\"0\"},\"actions\":{\"close\":0,\"open\":0,\"reconfigure\":0,\"reset\":0,\"sceneActivationSet\":0,\"setValue\":1,\"setValue2\":1,\"startLevelDecrease\":0,\"startLevelIncrease\":0,\"stop\":0,\"stopLevelChange\":0},\"created\":1516643106,\"modified\":1516643106,\"sortOrder\":15},{\"id\":112,\"name\":\"Stehlampe\",\"roomID\":12,\"type\":\"com.fibaro.multilevelSwitch\",\"baseType\":\"com.fibaro.binarySwitch\",\"enabled\":true,\"visible\":true,\"isPlugin\":false,\"parentId\":111,\"remoteGatewayId\":0,\"viewXml\":false,\"configXml\":false,\"interfaces\":[\"deviceGrouping\",\"fibaroFirmwareUpdate\",\"levelChange\",\"light\",\"zwave\",\"zwaveSwitchAll\"],\"properties\":{\"pollingTimeSec\":0,\"zwaveCompany\":\"Domitech Products\",\"zwaveInfo\":\"3,4,5\",\"zwaveVersion\":\"5.14\",\"configured\":true,\"dead\":\"false\",\"deviceControlType\":\"23\",\"deviceGroup\":\"[]\",\"deviceGroupMaster\":\"0\",\"deviceIcon\":\"15\",\"emailNotificationID\":\"0\",\"emailNotificationType\":\"0\",\"endPointId\":\"0\",\"firmwareUpdate\":\"{\\\"info\\\":\\\"\\\",\\\"progress\\\":0,\\\"status\\\":\\\"UpToDate\\\",\\\"updateVersion\\\":\\\"5.14\\\"}\",\"isLight\":\"true\",\"liliOffCommand\":\"\",\"liliOnCommand\":\"\",\"log\":\"\",\"logTemp\":\"\",\"manufacturer\":\"\",\"markAsDead\":\"true\",\"model\":\"\",\"nodeId\":\"27\",\"parametersTemplate\":\"807\",\"productInfo\":\"2,14,76,66,49,52,5,14\",\"pushNotificationID\":\"0\",\"pushNotificationType\":\"0\",\"remoteGatewayId\":\"0\",\"saveLogs\":\"true\",\"serialNumber\":\"\",\"smsNotificationID\":\"0\",\"smsNotificationType\":\"0\",\"switchAllMode\":\"SWITCH_ALL_INCLUDED_IN_THE_ALL_ON_ALL_OFF_FUNCTIONALITY\",\"updateVersion\":\"\",\"useTemplate\":\"true\",\"userDescription\":\"\",\"value\":\"0\"},\"actions\":{\"abortUpdate\":1,\"reconfigure\":0,\"retryUpdate\":1,\"setValue\":1,\"startLevelDecrease\":0,\"startLevelIncrease\":0,\"startUpdate\":1,\"stopLevelChange\":0,\"turnOff\":0,\"turnOn\":0,\"updateFirmware\":1},\"created\":1516643107,\"modified\":1516643107,\"sortOrder\":6},{\"id\":114,\"name\":\"RGBW\",\"roomID\":12,\"type\":\"com.fibaro.FGRGBW441M\",\"baseType\":\"com.fibaro.colorController\",\"enabled\":true,\"visible\":tr" +
|
||||
"ue,\"isPlugin\":false,\"parentId\":113,\"remoteGatewayId\":0,\"viewXml\":false,\"configXml\":false,\"interfaces\":[\"deviceGrouping\",\"energy\",\"fibaroFirmwareUpdate\",\"levelChange\",\"light\",\"power\",\"zwave\",\"zwaveSwitchAll\"],\"properties\":{\"pollingTimeSec\":0,\"zwaveCompany\":\"Fibargroup\",\"zwaveInfo\":\"3,3,52\",\"zwaveVersion\":\"26.25\",\"associationMode\":\"0\",\"brightness\":\"0\",\"buttonType\":\"0\",\"color\":\"0,0,0,0\",\"configured\":true,\"currentProgram\":\"0\",\"currentProgramID\":\"0\",\"dead\":\"false\",\"deviceControlType\":\"50\",\"deviceGroup\":\"[]\",\"deviceGroupMaster\":\"0\",\"deviceIcon\":\"15\",\"emailNotificationID\":\"0\",\"emailNotificationType\":\"0\",\"endPointId\":\"0\",\"energy\":\"1.72\",\"favoriteProgram\":\"0\",\"firmwareUpdate\":\"{\\\"info\\\":\\\"\\\",\\\"progress\\\":0,\\\"status\\\":\\\"UpToDate\\\",\\\"updateVersion\\\":\\\"26.25\\\"}\",\"isLight\":\"true\",\"lastColorSet\":\"0,0,0,0\",\"liliOffCommand\":\"\",\"liliOnCommand\":\"\",\"log\":\"\",\"logTemp\":\"\",\"manufacturer\":\"\",\"markAsDead\":\"true\",\"mode\":\"0\",\"model\":\"\",\"nodeId\":\"28\",\"parametersTemplate\":\"231\",\"power\":\"0.00\",\"productInfo\":\"1,15,9,0,16,0,26,25\",\"programsSortOrder\":\"1,2,3,4,5\",\"pushNotificationID\":\"0\",\"pushNotificationType\":\"0\",\"rememberColor\":\"false\",\"remoteGatewayId\":\"0\",\"saveLogs\":\"true\",\"serialNumber\":\"\",\"showEnergy\":\"true\",\"smsNotificationID\":\"0\",\"smsNotificationType\":\"0\",\"switchAllMode\":\"SWITCH_ALL_INCLUDED_IN_THE_ALL_ON_ALL_OFF_FUNCTIONALITY\",\"updateVersion\":\"\",\"useTemplate\":\"true\",\"userDescription\":\"\",\"value\":\"0\"},\"actions\":{\"abortUpdate\":1,\"reconfigure\":0,\"reset\":0,\"retryUpdate\":1,\"setB\":1,\"setBrightness\":1,\"setColor\":1,\"setFavoriteProgram\":2,\"setG\":1,\"setR\":1,\"setValue\":1,\"setW\":1,\"startLevelDecrease\":0,\"startLevelIncrease\":0,\"startProgram\":1,\"startUpdate\":1,\"stopLevelChange\":0,\"turnOff\":0,\"turnOn\":0,\"updateFirmware\":1},\"created\":1516643107,\"modified\":1516643107,\"sortOrder\":7},{\"id\":122,\"name\":\"Fenster\",\"roomID\":12,\"type\":\"com.fibaro.FGRM222\",\"baseType\":\"com.fibaro.FGR\",\"enabled\":true,\"visible\":true,\"isPlugin\":false,\"parentId\":121,\"remoteGatewayId\":0,\"viewXml\":false,\"configXml\":false,\"interfaces\":[\"energy\",\"fibaroFirmwareUpdate\",\"levelChange\",\"powe" +
|
||||
"r\",\"zwave\",\"zwaveConfiguration\",\"zwaveProtection\",\"zwaveSceneActivation\"],\"properties\":{\"pollingTimeSec\":0,\"zwaveCompany\":\"Fibargroup\",\"zwaveInfo\":\"3,3,52\",\"zwaveVersion\":\"24.24\",\"RFProtectionState\":\"0\",\"RFProtectionSupport\":\"3\",\"configured\":true,\"dead\":\"false\",\"deviceControlType\":\"54\",\"deviceIcon\":\"87\",\"emailNotificationID\":\"0\",\"emailNotificationType\":\"0\",\"endPointId\":\"0\",\"energy\":\"0.17\",\"firmwareUpdate\":\"{\\\"info\\\":\\\"\\\",\\\"progress\\\":0,\\\"status\\\":\\\"UpToDate\\\",\\\"updateVersion\\\":\\\"24.24\\\"}\",\"liliOffCommand\":\"\",\"liliOnCommand\":\"\",\"localProtectionState\":\"0\",\"localProtectionSupport\":\"5\",\"log\":\"\",\"logTemp\":\"\",\"manufacturer\":\"\",\"markAsDead\":\"true\",\"model\":\"\",\"nodeId\":\"29\",\"parametersTemplate\":\"249\",\"power\":\"0.00\",\"productInfo\":\"1,15,3,1,16,1,24,24\",\"protectionExclusiveControl\":\"0\",\"protectionExclusiveControlSupport\":\"false\",\"protectionState\":\"0\",\"protectionTimeout\":\"0\",\"protectionTimeoutSupport\":\"false\",\"pushNotificationID\":\"0\",\"pushNotificationType\":\"0\",\"remoteGatewayId\":\"0\",\"saveLogs\":\"true\",\"sceneActivation\":\"0\",\"serialNumber\":\"\",\"showEnergy\":\"true\",\"smsNotificationID\":\"0\",\"smsNotificationType\":\"0\",\"updateVersion\":\"\",\"useTemplate\":\"true\",\"userDescription\":\"\",\"value\":\"0\",\"value2\":\"0\"},\"actions\":{\"abortUpdate\":1,\"close\":0,\"getParameter\":1,\"open\":0,\"reconfigure\":0,\"reset\":0,\"retryUpdate\":1,\"sceneActivationSet\":0,\"setParameter\":2,\"setValue\":1,\"setValue2\":1,\"startLevelDecrease\":0,\"startLevelIncrease\":0,\"startUpdate\":1,\"stop\":0,\"stopLevelChange\":0,\"updateFirmware\":1},\"created\":1516643108,\"modified\":1516643108,\"sortOrder\":16}]";
|
||||
|
||||
public final static String RoomTestData = "[{\"id\":4,\"name\":\"Dachboden\",\"sectionID\":4,\"icon\":\"room_bedroom\",\"defaultSensors\":{\"temperature\":0,\"humidity\":0,\"light\":0},\"defaultThermostat\":0,\"sortOrder\":1},{\"id\":5,\"name\":\"Badezimmer\",\"sectionID\":5,\"icon\":\"room_wanna\",\"defaultSensors\":{\"temperature\":0,\"humidity\":0,\"light\":0},\"defaultThermostat\":0,\"sortOrder\":2},{\"id\":6,\"name\":\"Büro\",\"sectionID\":5,\"icon\":\"room_office\",\"defaultSensors\":{\"temperature\":0,\"humidity\":0,\"light\":0},\"defaultThermostat\":0,\"sortOrder\":3},{\"id\":7,\"name\":\"Flur\",\"sectionID\":5,\"icon\":\"room_schody2\",\"defaultSensors\":{\"temperature\":0,\"humidity\":0,\"light\":0},\"defaultThermostat\":0,\"sortOrder\":4},{\"id\":8,\"name\":\"Schlafzimmer\",\"sectionID\":5,\"icon\":\"room_bedroom\",\"defaultSensors\":{\"temperature\":0,\"humidity\":0,\"light\":0},\"defaultThermostat\":0,\"sortOrder\":5},{\"id\":9,\"name\":\"Emelie\",\"sectionID\":5,\"icon\":\"room_wardrobe\",\"defaultSensors\":{\"temperature\":0,\"humidity\":0,\"light\":0},\"defaultThermostat\":0,\"sortOrder\":6},{\"id\":10,\"name\":\"Mino\",\"sectionID\":5,\"icon\":\"room_garage\",\"defaultSensors\":{\"temperature\":0,\"humidity\":0,\"light\":0},\"defaultThermostat\":0,\"sortOrder\":7},{\"id\":11,\"name\":\"Flur\",\"sectionID\":6,\"icon\":\"room_drzwiwejsciowe\",\"defaultSensors\":{\"temperature\":181,\"humidity\":0,\"light\":182},\"defaultThermostat\":0,\"sortOrder\":8},{\"id\":12,\"name\":\"Wohnzimmer\",\"sectionID\":6,\"icon\":\"room_sofa\",\"defaultSensors\":{\"temperature\":0,\"humidity\":0,\"light\":0},\"defaultThermostat\":0,\"sortOrder\":9},{\"id\":13,\"name\":\"Küche\",\"sectionID\":6,\"icon\":\"room_dining\",\"defaultSensors\":{\"temperature\":0,\"humidity\":0,\"light\":0},\"defaultThermostat\":0,\"sortOrder\":10},{\"id\":14,\"name\":\"Esszimmer\",\"sectionID\":6,\"icon\":\"room_jadalnia\",\"defaultSensors\":{\"temperature\":0,\"humidity\":0,\"light\":0},\"defaultThermostat\":0,\"sortOrder\":11},{\"id\":15,\"name\":\"HWR\",\"sectionID\":6,\"icon\":\"room_laundry\",\"defaultSensors\":{\"temperature\":0,\"humidity\":0,\"light\":0},\"defaultThermostat\":0,\"sortOrder\":12},{\"id\":16,\"name\":\"Gäste WC\",\"sectionID\":6," +
|
||||
"\"icon\":\"room_toilet\",\"defaultSensors\":{\"temperature\":0,\"humidity\":0,\"light\":0},\"defaultThermostat\":0,\"sortOrder\":13},{\"id\":17,\"name\":\"Haus\",\"sectionID\":7,\"icon\":\"room_bedroom\",\"defaultSensors\":{\"temperature\":0,\"humidity\":0,\"light\":0},\"defaultThermostat\":0,\"sortOrder\":14},{\"id\":18,\"name\":\"Terrasse\",\"sectionID\":7,\"icon\":\"room_bedroom\",\"defaultSensors\":{\"temperature\":0,\"humidity\":0,\"light\":0},\"defaultThermostat\":0,\"sortOrder\":15}]";
|
||||
|
||||
public final static String SceneTestData = "[" +
|
||||
"{\"id\":33,\"name\":\"Fernsehlicht aus\",\"type\":\"com.fibaro.luaScene\",\"roomID\":12,\"iconID\":6,\"runConfig\":\"MANUAL_ONLY\",\"alexaProhibited\":true,\"autostart\":true,\"protectedByPIN\":false,\"killable\":true,\"killOtherInstances\":false,\"maxRunningInstances\":4,\"runningInstances\":0,\"instances\":[],\"runningManualInstances\":0,\"visible\":true,\"isLua\":true,\"properties\":\"\",\"triggers\":{\"properties\":[],\"globals\":[],\"events\":[],\"weather\":[]},\"actions\":{\"devices\":[],\"scenes\":[],\"groups\":[]},\"liliStartCommand\":\"\",\"liliStopCommand\":\"\",\"sortOrder\":17}," +
|
||||
"{\"id\":68,\"name\":\"Rollos runterfahren\",\"type\":\"com.fibaro.luaScene\",\"roomID\":14,\"iconID\":6,\"runConfig\":\"MANUAL_ONLY\",\"alexaProhibited\":true,\"autostart\":false,\"protectedByPIN\":false,\"killable\":true,\"killOtherInstances\":false,\"maxRunningInstances\":2,\"runningInstances\":0,\"instances\":[],\"runningManualInstances\":0,\"visible\":true,\"isLua\":true,\"properties\":\"\",\"triggers\":{\"properties\":[],\"globals\":[],\"events\":[],\"weather\":[]},\"actions\":{\"devices\":[],\"scenes\":[],\"groups\":[]},\"liliStartCommand\":\"\",\"liliStopCommand\":\"\",\"sortOrder\":8}," +
|
||||
"{\"id\":69,\"name\":\"Rollos hochfahren\",\"type\":\"com.fibaro.luaScene\",\"roomID\":14,\"iconID\":6,\"runConfig\":\"MANUAL_ONLY\",\"alexaProhibited\":true,\"autostart\":false,\"protectedByPIN\":false,\"killable\":true,\"killOtherInstances\":false,\"maxRunningInstances\":2,\"runningInstances\":0,\"instances\":[],\"runningManualInstances\":0,\"visible\":true,\"isLua\":true,\"properties\":\"\",\"triggers\":{\"properties\":[],\"globals\":[],\"events\":[],\"weather\":[]},\"actions\":{\"devices\":[],\"scenes\":[],\"groups\":[]},\"liliStartCommand\":\"\",\"liliStopCommand\":\"\",\"sortOrder\":9}," +
|
||||
"{\"id\":93,\"name\":\"Alles aus Haus\",\"type\":\"com.fibaro.magicScene\",\"roomID\":12,\"runConfig\":\"TRIGGER_AND_MANUAL\",\"alexaProhibited\":false,\"autostart\":false,\"protectedByPIN\":false,\"killable\":true,\"killOtherInstances\":false,\"maxRunningInstances\":2,\"runningInstances\":0,\"instances\":[],\"runningManualInstances\":0,\"visible\":false,\"properties\":\"{\\\"conditionDeviceId\\\":163,\\\"conditionObjectType\\\":\\\"device\\\",\\\"conditionId\\\":\\\"condition_centralSceneEvent1HeldDown_163\\\",\\\"conditionLua\\\":\\\"true\\\",\\\"conditionValue\\\":\\\"\\\",\\\"conditionRooms\\\":[],\\\"trigger\\\":\\\"163 CentralSceneEvent 1 HeldDown\\\\n163 CentralSceneEvent 1 Released\\\",\\\"actionDeviceId\\\":92,\\\"actionObjectType\\\":\\\"scene\\\",\\\"actionId\\\":\\\"action_runScene_92\\\",\\\"actionLua\\\":\\\"fibaro:startScene(92);\\\",\\\"actionValue\\\":\\\"\\\",\\\"actionRooms\\\":[],\\\"looping\\\":false}\",\"triggers\":{\"properties\":[],\"globals\":[],\"events\":[{\"deviceId\":163,\"eventName\":\"CentralSceneEvent\",\"args\":[\"1\",\"Released\"]}],\"weather\":[]},\"actions\":{\"devices\":[],\"scenes\":[92],\"groups\":[]},\"liliStartCommand\":\"\",\"liliStopCommand\":\"\",\"sortOrder\":18}," +
|
||||
"{\"id\":94,\"name\":\"Fernsehlicht an\",\"type\":\"com.fibaro.blockScene\",\"roomID\":12,\"iconID\":5,\"runConfig\":\"MANUAL_ONLY\",\"alexaProhibited\":false,\"autostart\":true,\"protectedByPIN\":false,\"killable\":true,\"killOtherInstances\":false,\"maxRunningInstances\":2,\"runningInstances\":0,\"instances\":[],\"runningManualInstances\":0,\"visible\":true,\"isLua\":false,\"properties\":\"\",\"triggers\":{\"properties\":[],\"globals\":[],\"events\":[],\"weather\":[]},\"actions\":{\"devices\":[112,114],\"scenes\":[],\"groups\":[]},\"liliStartCommand\":\"\",\"liliStopCommand\":\"\",\"sortOrder\":10}," +
|
||||
"{\"id\":95,\"name\":\"Fernsehlicht + aus\",\"type\":\"com.fibaro.blockScene\",\"roomID\":12,\"iconID\":5,\"runConfig\":\"MANUAL_ONLY\",\"alexaProhibited\":false,\"autostart\":true,\"protectedByPIN\":false,\"killable\":true,\"killOtherInstances\":false,\"maxRunningInstances\":2,\"runningInstances\":0,\"instances\":[],\"runningManualInstances\":0,\"visible\":true,\"isLua\":false,\"properties\":\"\",\"triggers\":{\"properties\":[],\"globals\":[],\"events\":[],\"weather\":[]},\"actions\":{\"devices\":[7,10,11,12,13,14,57,60,74,77,97,112,114],\"scenes\":[],\"groups\":[]},\"liliStartCommand\":\"\",\"liliStopCommand\":\"\",\"sortOrder\":19}," +
|
||||
"{\"id\":96,\"name\":\"Fernsehlicht Wohnzim\",\"type\":\"com.fibaro.magicScene\",\"roomID\":12,\"runConfig\":\"TRIGGER_AND_MANUAL\",\"alexaProhibited\":false,\"autostart\":false,\"protectedByPIN\":false,\"killable\":true,\"killOtherInstances\":false,\"maxRunningInstances\":2,\"runningInstances\":0,\"instances\":[],\"runningManualInstances\":0,\"visible\":false,\"properties\":\"{\\\"conditionDeviceId\\\":163,\\\"conditionObjectType\\\":\\\"device\\\",\\\"conditionId\\\":\\\"condition_centralSceneEvent2Pressed_163\\\",\\\"conditionLua\\\":\\\"true\\\",\\\"conditionValue\\\":\\\"\\\",\\\"conditionRooms\\\":[],\\\"trigger\\\":\\\"163 CentralSceneEvent 2 Pressed\\\",\\\"actionDeviceId\\\":94,\\\"actionObjectType\\\":\\\"scene\\\",\\\"actionId\\\":\\\"action_runScene_94\\\",\\\"actionLua\\\":\\\"fibaro:startScene(94);\\\",\\\"actionValue\\\":\\\"\\\",\\\"actionRooms\\\":[],\\\"looping\\\":false}\",\"triggers\":{\"properties\":[],\"globals\":[],\"events\":[{\"deviceId\":163,\"eventName\":\"CentralSceneEvent\",\"args\":[\"2\",\"Pressed\"]}],\"weather\":[]},\"actions\":{\"devices\":[],\"scenes\":[94],\"groups\":[]},\"liliStartCommand\":\"\",\"liliStopCommand\":\"\",\"sortOrder\":20}," +
|
||||
"{\"id\":98,\"name\":\"Fersehlicht blau\",\"type\":\"com.fibaro.blockScene\",\"roomID\":12,\"iconID\":5,\"runConfig\":\"MANUAL_ONLY\",\"alexaProhibited\":false,\"autostart\":true,\"protectedByPIN\":false,\"killable\":true,\"killOtherInstances\":false,\"maxRunningInstances\":2,\"runningInstances\":0,\"instances\":[],\"runningManualInstances\":0,\"visible\":true,\"isLua\":false,\"properties\":\"\",\"triggers\":{\"properties\":[],\"globals\":[],\"events\":[],\"weather\":[]},\"actions\":{\"devices\":[112,114],\"scenes\":[],\"groups\":[]},\"liliStartCommand\":\"\",\"liliStopCommand\":\"\",\"sortOrder\":11}," +
|
||||
"{\"id\":99,\"name\":\"Fernsehlicht blau+au\",\"type\":\"com.fibaro.blockScene\",\"roomID\":12,\"iconID\":5,\"runConfig\":\"MANUAL_ONLY\",\"alexaProhibited\":false,\"autostart\":true,\"protectedByPIN\":false,\"killable\":true,\"killOtherInstances\":false,\"maxRunningInstances\":2,\"runningInstances\":0,\"instances\":[],\"runningManualInstances\":0,\"visible\":true,\"isLua\":false,\"properties\":\"\",\"triggers\":{\"properties\":[],\"globals\":[],\"events\":[],\"weather\":[]},\"actions\":{\"devices\":[7,10,11,12,13,14,112,114],\"scenes\":[],\"groups\":[]},\"liliStartCommand\":\"\",\"liliStopCommand\":\"\",\"sortOrder\":21}," +
|
||||
"{\"id\":100,\"name\":\"Fernsehlicht blau+au\",\"type\":\"com.fibaro.magicScene\",\"roomID\":12,\"runConfig\":\"TRIGGER_AND_MANUAL\",\"alexaProhibited\":false,\"autostart\":false,\"protectedByPIN\":false,\"killable\":true,\"killOtherInstances\":false,\"maxRunningInstances\":2,\"runningInstances\":0,\"instances\":[],\"runningManualInstances\":0,\"visible\":false,\"properties\":\"{\\\"conditionDeviceId\\\":163,\\\"conditionObjectType\\\":\\\"device\\\",\\\"conditionId\\\":\\\"condition_centralSceneEvent3HeldDown_163\\\",\\\"conditionLua\\\":\\\"true\\\",\\\"conditionValue\\\":\\\"\\\",\\\"conditionRooms\\\":[],\\\"trigger\\\":\\\"163 CentralSceneEvent 3 HeldDown\\\\n163 CentralSceneEvent 3 Released\\\",\\\"actionDeviceId\\\":99,\\\"actionObjectType\\\":\\\"scene\\\",\\\"actionId\\\":\\\"action_runScene_99\\\",\\\"actionLua\\\":\\\"fibaro:startScene(99);\\\",\\\"actionValue\\\":\\\"\\\",\\\"actionRooms\\\":[],\\\"looping\\\":false}\",\"triggers\":{\"properties\":[],\"globals\":[],\"events\":[{\"deviceId\":163,\"eventName\":\"CentralSceneEvent\",\"args\":[\"3\",\"Released\"]}],\"weather\":[]},\"actions\":{\"devices\":[],\"scenes\":[99],\"groups\":[]},\"liliStartCommand\":\"\",\"liliStopCommand\":\"\",\"sortOrder\":22}," +
|
||||
"{\"id\":101,\"name\":\"Fersehlicht blau Woh\",\"type\":\"com.fibaro.magicScene\",\"roomID\":12,\"runConfig\":\"TRIGGER_AND_MANUAL\",\"alexaProhibited\":false,\"autostart\":false,\"protectedByPIN\":false,\"killable\":true,\"killOtherInstances\":false,\"maxRunningInstances\":2,\"runningInstances\":0,\"instances\":[],\"runningManualInstances\":0,\"visible\":false,\"properties\":\"{\\\"conditionDeviceId\\\":163,\\\"conditionObjectType\\\":\\\"device\\\",\\\"conditionId\\\":\\\"condition_centralSceneEvent3Pressed_163\\\",\\\"conditionLua\\\":\\\"true\\\",\\\"conditionValue\\\":\\\"\\\",\\\"conditionRooms\\\":[],\\\"trigger\\\":\\\"163 CentralSceneEvent 3 Pressed\\\",\\\"actionDeviceId\\\":98,\\\"actionObjectType\\\":\\\"scene\\\",\\\"actionId\\\":\\\"action_runScene_98\\\",\\\"actionLua\\\":\\\"fibaro:startScene(98);\\\",\\\"actionValue\\\":\\\"\\\",\\\"actionRooms\\\":[],\\\"looping\\\":false}\",\"triggers\":{\"properties\":[],\"globals\":[],\"events\":[{\"deviceId\":163,\"eventName\":\"CentralSceneEvent\",\"args\":[\"3\",\"Pressed\"]}],\"weather\":[]},\"actions\":{\"devices\":[],\"scenes\":[98],\"groups\":[]},\"liliStartCommand\":\"\",\"liliStopCommand\":\"\",\"sortOrder\":23}" +
|
||||
"]";
|
||||
|
||||
public final static String CallActionTestData = "Fiabro action received";
|
||||
public final static String SceneControlTestData = "Fiabro scene control received";
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package com.bwssystems.HABridge.plugins.fibaro;
|
||||
|
||||
public enum ModeType {
|
||||
OFF(0, "Off"),
|
||||
HEAT(1, "Heat"),
|
||||
COOL(2, "Cool"),
|
||||
AUTO(3, "Auto"),
|
||||
AUX_HEAT(4, "Aux Heat"),
|
||||
RESUME(5, "Resume"),
|
||||
FAN_ONLY(6, "Fan Only"),
|
||||
FURNANCE(7, "Furnace"),
|
||||
DRY_AIR(8, "Dry Air"),
|
||||
MOIST_AIR(9, "Moist Air"),
|
||||
AUTO_CHANGEOVER(10, "Auto Changeover"),
|
||||
HEAT_ECON(11, "Heat Econ"),
|
||||
COOL_ECON(12, "Cool Econ"),
|
||||
AWAY(13, "Away"),
|
||||
MANUAL(31, "Manual");
|
||||
|
||||
private int key;
|
||||
private String label;
|
||||
|
||||
private ModeType(int key, String label) {
|
||||
this.key = key;
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public int getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
}
|
||||
@@ -17,48 +17,9 @@ public class Device {
|
||||
@SerializedName("type")
|
||||
private String type;
|
||||
|
||||
@SerializedName("baseType")
|
||||
private String baseType;
|
||||
|
||||
@SerializedName("enabled")
|
||||
private boolean enabled;
|
||||
|
||||
@SerializedName("visible")
|
||||
private boolean visible;
|
||||
|
||||
@SerializedName("isPlugin")
|
||||
private boolean isPlugin;
|
||||
|
||||
@SerializedName("parentId")
|
||||
private int parentId;
|
||||
|
||||
@SerializedName("remoteGatewayId")
|
||||
private int remoteGatewayId;
|
||||
|
||||
@SerializedName("viewXml")
|
||||
private boolean viewXml;
|
||||
|
||||
@SerializedName("configXml")
|
||||
private boolean configXml;
|
||||
|
||||
@SerializedName("interfaces")
|
||||
private Object interfaces;
|
||||
|
||||
@SerializedName("properties")
|
||||
private DeviceProperties properties;
|
||||
|
||||
@SerializedName("actions")
|
||||
private Object actions;
|
||||
|
||||
@SerializedName("created")
|
||||
private int created;
|
||||
|
||||
@SerializedName("modified")
|
||||
private int modified;
|
||||
|
||||
@SerializedName("sortOrder")
|
||||
private int sortOrder;
|
||||
|
||||
public String getRoomName() {
|
||||
return roomName;
|
||||
}
|
||||
|
||||
@@ -3,242 +3,21 @@ package com.bwssystems.HABridge.plugins.fibaro.json;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class DeviceProperties {
|
||||
@SerializedName("batteryLevel")
|
||||
private String batteryLevel;
|
||||
|
||||
@SerializedName("UIMessageSendTime")
|
||||
private String UIMessageSendTime;
|
||||
|
||||
@SerializedName("autoConfig")
|
||||
private String autoConfig;
|
||||
|
||||
@SerializedName("color")
|
||||
private String color;
|
||||
|
||||
@SerializedName("date")
|
||||
private String date;
|
||||
|
||||
@SerializedName("dead")
|
||||
private String dead;
|
||||
|
||||
@SerializedName("deviceControlType")
|
||||
private String deviceControlType;
|
||||
|
||||
@SerializedName("deviceIcon")
|
||||
private String deviceIcon;
|
||||
|
||||
@SerializedName("disabled")
|
||||
private String disabled;
|
||||
|
||||
@SerializedName("emailNotificationID")
|
||||
private String emailNotificationID;
|
||||
|
||||
@SerializedName("emailNotificationType")
|
||||
private String emailNotificationType;
|
||||
|
||||
@SerializedName("endPoint")
|
||||
private String endPoint;
|
||||
|
||||
@SerializedName("energy")
|
||||
private String energy;
|
||||
|
||||
@SerializedName("liliOffCommand")
|
||||
private String liliOffCommand;
|
||||
|
||||
@SerializedName("liliOnCommand")
|
||||
private String liliOnCommand;
|
||||
|
||||
@SerializedName("log")
|
||||
private String log;
|
||||
|
||||
@SerializedName("logTemp")
|
||||
private String logTemp;
|
||||
|
||||
@SerializedName("manufacturer")
|
||||
private String manufacturer;
|
||||
|
||||
@SerializedName("markAsDead")
|
||||
private String markAsDead;
|
||||
|
||||
@SerializedName("mode")
|
||||
private String mode;
|
||||
|
||||
@SerializedName("model")
|
||||
private String model;
|
||||
|
||||
@SerializedName("nodeID")
|
||||
private String nodeID;
|
||||
|
||||
@SerializedName("pollingDeadDevice")
|
||||
private String pollingDeadDevice;
|
||||
|
||||
@SerializedName("pollingTime")
|
||||
private String pollingTime;
|
||||
|
||||
@SerializedName("pollingTimeNext")
|
||||
private String pollingTimeNext;
|
||||
|
||||
@SerializedName("pollingTimeSec")
|
||||
private int pollingTimeSec;
|
||||
|
||||
@SerializedName("power")
|
||||
private String power;
|
||||
|
||||
@SerializedName("productInfo")
|
||||
private String productInfo;
|
||||
|
||||
@SerializedName("pushNotificationID")
|
||||
private String pushNotificationID;
|
||||
|
||||
@SerializedName("pushNotificationType")
|
||||
private String pushNotificationType;
|
||||
|
||||
@SerializedName("remoteGatewayId")
|
||||
private String remoteGatewayId;
|
||||
|
||||
@SerializedName("requestNodeNeighborStat")
|
||||
private String requestNodeNeighborStat;
|
||||
|
||||
@SerializedName("requestNodeNeighborStatTimeStemp")
|
||||
private String requestNodeNeighborStatTimeStemp;
|
||||
|
||||
@SerializedName("requestNodeNeighborState")
|
||||
private String requestNodeNeighborState;
|
||||
|
||||
@SerializedName("requestNodeNeighborStateTimeStemp")
|
||||
private String requestNodeNeighborStateTimeStemp;
|
||||
@SerializedName("value")
|
||||
private String value;
|
||||
|
||||
@SerializedName("saveLogs")
|
||||
private String saveLogs;
|
||||
|
||||
@SerializedName("showChildren")
|
||||
private String showChildren;
|
||||
|
||||
@SerializedName("smsNotificationID")
|
||||
private String smsNotificationID;
|
||||
|
||||
@SerializedName("smsNotificationType")
|
||||
private String smsNotificationType;
|
||||
|
||||
@SerializedName("supportedModes")
|
||||
private String supportedModes;
|
||||
|
||||
@SerializedName("targetLevel")
|
||||
private String targetLevel;
|
||||
|
||||
@SerializedName("unit")
|
||||
private String unit;
|
||||
|
||||
@SerializedName("useTemplate")
|
||||
private String useTemplate;
|
||||
|
||||
@SerializedName("status")
|
||||
private String status;
|
||||
|
||||
@SerializedName("sunriseHour")
|
||||
private String sunriseHour;
|
||||
|
||||
@SerializedName("sunsetHour")
|
||||
private String sunsetHour;
|
||||
|
||||
@SerializedName("userDescription")
|
||||
private String userDescription;
|
||||
|
||||
@SerializedName("value")
|
||||
private String value;
|
||||
|
||||
@SerializedName("zwaveBuildVersion")
|
||||
private String zwaveBuildVersion;
|
||||
|
||||
@SerializedName("zwaveCompany")
|
||||
private String zwaveCompany;
|
||||
|
||||
@SerializedName("zwaveInfo")
|
||||
private String zwaveInfo;
|
||||
|
||||
@SerializedName("zwaveRegion")
|
||||
private String zwaveRegion;
|
||||
|
||||
@SerializedName("zwaveVersion")
|
||||
private double zwaveVersion;
|
||||
|
||||
public String getBatteryLevel() {
|
||||
return batteryLevel;
|
||||
}
|
||||
|
||||
public String getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public String getDeviceControlType() {
|
||||
return deviceControlType;
|
||||
}
|
||||
|
||||
public String getEnergy() {
|
||||
return energy;
|
||||
}
|
||||
|
||||
public String getPower() {
|
||||
return power;
|
||||
}
|
||||
|
||||
public String getTargetLevel() {
|
||||
return targetLevel;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
// --- begin yrWeather plugin ---
|
||||
@SerializedName("Humidity")
|
||||
private String Humidity;
|
||||
|
||||
@SerializedName("Pressure")
|
||||
private String Pressure;
|
||||
|
||||
@SerializedName("Temperature")
|
||||
private String Temperature;
|
||||
|
||||
@SerializedName("WeatherCondition")
|
||||
private String WeatherCondition;
|
||||
|
||||
@SerializedName("Wind")
|
||||
private String Wind;
|
||||
|
||||
public String getHumidity() {
|
||||
return Humidity;
|
||||
}
|
||||
|
||||
public String getPressure() {
|
||||
return Pressure;
|
||||
}
|
||||
|
||||
public String getSaveLogs()
|
||||
{
|
||||
return saveLogs;
|
||||
}
|
||||
|
||||
public String getTemperature() {
|
||||
return Temperature;
|
||||
}
|
||||
|
||||
public String getWeatherCondition() {
|
||||
return WeatherCondition;
|
||||
}
|
||||
|
||||
public String getWind() {
|
||||
return Wind;
|
||||
}
|
||||
// --- end yrWeather plugin ---
|
||||
|
||||
public String getUserDescription()
|
||||
{
|
||||
return userDescription;
|
||||
}
|
||||
|
||||
public void setUserDescription(String userDescription)
|
||||
{
|
||||
this.userDescription = userDescription;
|
||||
}
|
||||
public String getSaveLogs() {
|
||||
return saveLogs;
|
||||
}
|
||||
public String getUserDescription() {
|
||||
return userDescription;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,18 +12,6 @@ public class Room {
|
||||
@SerializedName("sectionID")
|
||||
private int sectionID;
|
||||
|
||||
@SerializedName("icon")
|
||||
private String icon;
|
||||
|
||||
@SerializedName("defaultSensors")
|
||||
private Sensor defaultSensors;
|
||||
|
||||
@SerializedName("defaultThermostat")
|
||||
private int defaultThermostat;
|
||||
|
||||
@SerializedName("sortOrder")
|
||||
private int sortOrder;
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@@ -14,51 +14,12 @@ public class Scene {
|
||||
@SerializedName("type")
|
||||
private String type;
|
||||
|
||||
@SerializedName("properties")
|
||||
private String properties;
|
||||
|
||||
@SerializedName("roomID")
|
||||
private int roomID;
|
||||
|
||||
@SerializedName("iconID")
|
||||
private int iconID;
|
||||
|
||||
@SerializedName("runConfig")
|
||||
private String runConfig;
|
||||
|
||||
@SerializedName("autostart")
|
||||
private boolean autostart;
|
||||
|
||||
@SerializedName("protectedByPIN")
|
||||
private boolean protectedByPIN;
|
||||
|
||||
@SerializedName("killable")
|
||||
private boolean killable;
|
||||
|
||||
@SerializedName("maxRunningInstances")
|
||||
private int maxRunningInstances;
|
||||
|
||||
@SerializedName("runningInstances")
|
||||
private int runningInstances;
|
||||
|
||||
@SerializedName("visible")
|
||||
private boolean visible;
|
||||
|
||||
@SerializedName("isLua")
|
||||
private boolean isLua;
|
||||
|
||||
@SerializedName("triggers")
|
||||
private SceneTriggers triggers;
|
||||
|
||||
@SerializedName("liliStartCommand")
|
||||
private String liliStartCommand;
|
||||
|
||||
@SerializedName("liliStopCommand")
|
||||
private String liliStopCommand;
|
||||
|
||||
@SerializedName("sortOrder")
|
||||
private int sortOrder;
|
||||
|
||||
public String getRoomName() {
|
||||
return roomName;
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
package com.bwssystems.HABridge.plugins.fibaro.json;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class SceneProperties {
|
||||
@SerializedName("id")
|
||||
private String id;
|
||||
|
||||
@SerializedName("name")
|
||||
private String name;
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package com.bwssystems.HABridge.plugins.fibaro.json;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class SceneTriggers {
|
||||
@SerializedName("properties")
|
||||
private SceneProperties[] properties;
|
||||
|
||||
@SerializedName("globals")
|
||||
private String[] globals;
|
||||
|
||||
@SerializedName("events")
|
||||
private String[] events;
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package com.bwssystems.HABridge.plugins.fibaro.json;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class Sensor {
|
||||
@SerializedName("temperature")
|
||||
private int temperature;
|
||||
|
||||
@SerializedName("humidity")
|
||||
private int humidity;
|
||||
|
||||
@SerializedName("light")
|
||||
private int light;
|
||||
}
|
||||
@@ -104,7 +104,7 @@ public class HalHome implements Home {
|
||||
|
||||
private Boolean addHalDevices(List<HalDevice> theDeviceList, List<HalDevice> theSourceList, String theKey) {
|
||||
if(!validHal)
|
||||
return null;
|
||||
return false;
|
||||
Iterator<HalDevice> devices = theSourceList.iterator();
|
||||
while(devices.hasNext()) {
|
||||
HalDevice theDevice = devices.next();
|
||||
@@ -113,12 +113,17 @@ public class HalHome implements Home {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh() {
|
||||
// noop
|
||||
}
|
||||
|
||||
@Override
|
||||
public String deviceHandler(CallItem anItem, MultiCommandUtil aMultiUtil, String lightId, int intensity,
|
||||
Integer targetBri,Integer targetBriInc, ColorData colorData, DeviceDescriptor device, String body) {
|
||||
boolean halFound = false;
|
||||
String responseString = null;
|
||||
String theUrl = anItem.getItem().getAsString();
|
||||
String theUrl = anItem.getItem().getAsString().replaceAll("^\"|\"$", "");
|
||||
if(theUrl != null && !theUrl.isEmpty () && theUrl.contains("http")) {
|
||||
String intermediate = theUrl.substring(theUrl.indexOf("://") + 3);
|
||||
String hostPortion = intermediate.substring(0, intermediate.indexOf('/'));
|
||||
@@ -160,7 +165,7 @@ public class HalHome implements Home {
|
||||
log.warn("Error on calling hal to change device state: " + anUrl);
|
||||
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
|
||||
"Error on calling url to change device state", "/lights/"
|
||||
+ lightId + "state", null, null).getTheErrors(), HueError[].class);
|
||||
+ lightId + "/state", null, null).getTheErrors(), HueError[].class);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -170,7 +175,7 @@ public class HalHome implements Home {
|
||||
log.warn("No HAL found to call: " + theUrl);
|
||||
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
|
||||
"No HAL found.", "/lights/"
|
||||
+ lightId + "state", null, null).getTheErrors(), HueError[].class);
|
||||
+ lightId + "/state", null, null).getTheErrors(), HueError[].class);
|
||||
}
|
||||
return responseString;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.whistlingfish.harmony.HarmonyClient;
|
||||
import net.whistlingfish.harmony.config.Activity;
|
||||
import net.whistlingfish.harmony.config.Device;
|
||||
import net.whistlingfish.harmony.config.HarmonyConfig;
|
||||
import com.bwssystems.HABridge.NamedIP;
|
||||
|
||||
public class HarmonyHandler {
|
||||
private static final Logger log = LoggerFactory.getLogger(HarmonyHandler.class);
|
||||
@@ -16,8 +17,9 @@ public class HarmonyHandler {
|
||||
private Boolean noopCalls;
|
||||
private Boolean devMode;
|
||||
private DevModeResponse devResponse;
|
||||
private NamedIP myNameAndIP;
|
||||
|
||||
public HarmonyHandler(HarmonyClient theClient, Boolean noopCallsSetting, DevModeResponse devResponseSetting) {
|
||||
public HarmonyHandler(HarmonyClient theClient, Boolean noopCallsSetting, DevModeResponse devResponseSetting, NamedIP aNameAndIP) {
|
||||
super();
|
||||
noopCalls = noopCallsSetting;
|
||||
devMode = Boolean.TRUE;
|
||||
@@ -27,6 +29,7 @@ public class HarmonyHandler {
|
||||
else
|
||||
devResponse = devResponseSetting;
|
||||
harmonyClient = theClient;
|
||||
myNameAndIP = aNameAndIP;
|
||||
}
|
||||
|
||||
public List<Activity> getActivities() {
|
||||
@@ -34,7 +37,16 @@ public class HarmonyHandler {
|
||||
if(devMode)
|
||||
return devResponse.getActivities();
|
||||
|
||||
return harmonyClient.getConfig().getActivities();
|
||||
List<Activity> listOfActivities = null;
|
||||
|
||||
try {
|
||||
listOfActivities = harmonyClient.getConfig().getActivities();
|
||||
} catch (RuntimeException e) {
|
||||
handleExceptionError(e);
|
||||
return null;
|
||||
}
|
||||
|
||||
return listOfActivities;
|
||||
}
|
||||
|
||||
public List<Device> getDevices() {
|
||||
@@ -42,7 +54,15 @@ public class HarmonyHandler {
|
||||
if(devMode)
|
||||
return devResponse.getDevices();
|
||||
|
||||
return harmonyClient.getConfig().getDevices();
|
||||
List<Device> listOfDevices = null;
|
||||
|
||||
try {
|
||||
listOfDevices = harmonyClient.getConfig().getDevices();
|
||||
} catch (RuntimeException e) {
|
||||
handleExceptionError(e);
|
||||
return null;
|
||||
}
|
||||
return listOfDevices;
|
||||
}
|
||||
|
||||
public HarmonyConfig getConfig() {
|
||||
@@ -50,15 +70,29 @@ public class HarmonyHandler {
|
||||
if(devMode)
|
||||
return devResponse.getConfig();
|
||||
|
||||
return harmonyClient.getConfig();
|
||||
HarmonyConfig aConfig = null;
|
||||
try {
|
||||
aConfig = harmonyClient.getConfig();
|
||||
} catch (RuntimeException e) {
|
||||
handleExceptionError(e);
|
||||
return null;
|
||||
}
|
||||
return aConfig;
|
||||
}
|
||||
|
||||
public Activity getCurrentActivity() {
|
||||
log.debug("Harmony api current sctivity requested.");
|
||||
if(devMode)
|
||||
return devResponse.getCurrentActivity();
|
||||
|
||||
return harmonyClient.getCurrentActivity();
|
||||
|
||||
Activity anActivity = null;
|
||||
try {
|
||||
anActivity = harmonyClient.getCurrentActivity();
|
||||
} catch (RuntimeException e) {
|
||||
handleExceptionError(e);
|
||||
return null;
|
||||
}
|
||||
return anActivity;
|
||||
}
|
||||
|
||||
public Boolean startActivity(RunActivity anActivity) {
|
||||
@@ -82,12 +116,14 @@ public class HarmonyHandler {
|
||||
harmonyClient.startActivityByName(anActivity.getName());
|
||||
} catch (IllegalArgumentException ei) {
|
||||
log.error("Error in finding activity: " + anActivity.getName() + " for a hub: " + anActivity.getHub());
|
||||
return false;
|
||||
} catch (RuntimeException e1) {
|
||||
return handleExceptionError(e1);
|
||||
}
|
||||
} catch (RuntimeException e1) {
|
||||
return handleExceptionError(e1);
|
||||
}
|
||||
} else {
|
||||
log.error("Error in finding activity: " + anActivity.getName() + " for a hub: " + anActivity.getHub());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -113,11 +149,22 @@ public class HarmonyHandler {
|
||||
harmonyClient.pressButton(aDeviceButton.getDevice(), aDeviceButton.getButton());
|
||||
} catch (IllegalArgumentException ei) {
|
||||
log.error("Error in finding device: " + aDeviceButton.getDevice() +" and a button: " + aDeviceButton.getButton() + " for a hub: " + aDeviceButton.getHub());
|
||||
return false;
|
||||
} catch (RuntimeException e1) {
|
||||
return handleExceptionError(e1);
|
||||
}
|
||||
} catch (RuntimeException e1) {
|
||||
return handleExceptionError(e1);
|
||||
}
|
||||
} else {
|
||||
log.error("Error in finding device: " + aDeviceButton.getDevice() +" and a button: " + aDeviceButton.getButton() + " for a hub: " + aDeviceButton.getHub());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean handleExceptionError(Exception e) {
|
||||
if(e.getMessage().contains("Failed communicating with Harmony Hub") || e.getMessage().contains("Send heartbeat failed")) {
|
||||
log.warn("Issue in communcicating with Harmony Hub, retrying connect....");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -128,9 +175,19 @@ public class HarmonyHandler {
|
||||
log.debug("Harmony api shutdown requested.");
|
||||
if(devMode)
|
||||
return;
|
||||
|
||||
harmonyClient.disconnect();
|
||||
try {
|
||||
harmonyClient.disconnect();
|
||||
} catch(Exception e)
|
||||
{
|
||||
// noop
|
||||
}
|
||||
harmonyClient = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the myNameAndIP
|
||||
*/
|
||||
public NamedIP getMyNameAndIP() {
|
||||
return myNameAndIP;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ import net.whistlingfish.harmony.config.Activity;
|
||||
import net.whistlingfish.harmony.config.Device;
|
||||
|
||||
public class HarmonyHome implements Home {
|
||||
private static final Logger log = LoggerFactory.getLogger(HarmonyHome.class);
|
||||
private static final Logger log = LoggerFactory.getLogger(HarmonyHome.class);
|
||||
private Map<String, HarmonyServer> hubs;
|
||||
private Boolean isDevMode;
|
||||
private Boolean validHarmony;
|
||||
@@ -43,91 +43,136 @@ public class HarmonyHome implements Home {
|
||||
|
||||
@Override
|
||||
public void closeHome() {
|
||||
if(!validHarmony)
|
||||
if (!validHarmony)
|
||||
return;
|
||||
log.debug("Closing Home.");
|
||||
if(closed) {
|
||||
if (closed) {
|
||||
log.debug("Home is already closed....");
|
||||
return;
|
||||
}
|
||||
if(isDevMode || hubs == null)
|
||||
if (isDevMode || hubs == null)
|
||||
return;
|
||||
Iterator<String> keys = hubs.keySet().iterator();
|
||||
while(keys.hasNext()) {
|
||||
while (keys.hasNext()) {
|
||||
String key = keys.next();
|
||||
hubs.get(key).getMyHarmony().shutdown();
|
||||
}
|
||||
|
||||
|
||||
hubs = null;
|
||||
closed = true;
|
||||
}
|
||||
|
||||
public HarmonyHandler getHarmonyHandler(String aName) {
|
||||
if(!validHarmony)
|
||||
if (!validHarmony)
|
||||
return null;
|
||||
HarmonyHandler aHandler = null;
|
||||
if(aName == null || aName.equals("")) {
|
||||
if (aName == null || aName.equals("")) {
|
||||
aName = "default";
|
||||
}
|
||||
|
||||
if(hubs.get(aName) == null) {
|
||||
if (hubs.get(aName) == null) {
|
||||
Set<String> keys = hubs.keySet();
|
||||
if(!keys.isEmpty()) {
|
||||
if (!keys.isEmpty()) {
|
||||
aHandler = hubs.get(keys.toArray()[0]).getMyHarmony();
|
||||
}
|
||||
else
|
||||
} else
|
||||
aHandler = null;
|
||||
}
|
||||
else
|
||||
} else
|
||||
aHandler = hubs.get(aName).getMyHarmony();
|
||||
return aHandler;
|
||||
}
|
||||
|
||||
|
||||
public List<HarmonyActivity> getActivities() {
|
||||
Iterator<String> keys = hubs.keySet().iterator();
|
||||
ArrayList<HarmonyActivity> activityList = new ArrayList<HarmonyActivity>();
|
||||
if(!validHarmony)
|
||||
if (!validHarmony)
|
||||
return null;
|
||||
while(keys.hasNext()) {
|
||||
while (keys.hasNext()) {
|
||||
String key = keys.next();
|
||||
Iterator<Activity> activities = hubs.get(key).getMyHarmony().getActivities().iterator();
|
||||
while(activities.hasNext()) {
|
||||
if (activities == null) {
|
||||
resetHub(hubs.get(key).getMyHarmony());
|
||||
activities = hubs.get(key).getMyHarmony().getActivities().iterator();
|
||||
if (activities == null) {
|
||||
if (resetHub(hubs.get(key).getMyHarmony())) {
|
||||
activities = hubs.get(key).getMyHarmony().getActivities().iterator();
|
||||
if (activities == null) {
|
||||
log.error("Could not get communication restored with hub: " + key
|
||||
+ ", please restart...");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (activities != null) {
|
||||
while (activities.hasNext()) {
|
||||
HarmonyActivity anActivity = new HarmonyActivity();
|
||||
anActivity.setActivity(activities.next());
|
||||
anActivity.setHub(key);
|
||||
activityList.add(anActivity);
|
||||
}
|
||||
}
|
||||
}
|
||||
return activityList;
|
||||
}
|
||||
|
||||
public List<HarmonyActivity> getCurrentActivities() {
|
||||
Iterator<String> keys = hubs.keySet().iterator();
|
||||
ArrayList<HarmonyActivity> activityList = new ArrayList<HarmonyActivity>();
|
||||
if (!validHarmony)
|
||||
return null;
|
||||
while (keys.hasNext()) {
|
||||
String key = keys.next();
|
||||
Activity theActivity = hubs.get(key).getMyHarmony().getCurrentActivity();
|
||||
if (theActivity == null) {
|
||||
resetHub(hubs.get(key).getMyHarmony());
|
||||
theActivity = hubs.get(key).getMyHarmony().getCurrentActivity();
|
||||
if (theActivity == null) {
|
||||
if (resetHub(hubs.get(key).getMyHarmony())) {
|
||||
theActivity = hubs.get(key).getMyHarmony().getCurrentActivity();
|
||||
if (theActivity == null) {
|
||||
log.error("Could not get communication restored with hub: " + key
|
||||
+ ", please restart...");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (theActivity != null) {
|
||||
HarmonyActivity anActivity = new HarmonyActivity();
|
||||
anActivity.setActivity(activities.next());
|
||||
anActivity.setActivity(theActivity);
|
||||
anActivity.setHub(key);
|
||||
activityList.add(anActivity);
|
||||
}
|
||||
}
|
||||
return activityList;
|
||||
}
|
||||
public List<HarmonyActivity> getCurrentActivities() {
|
||||
Iterator<String> keys = hubs.keySet().iterator();
|
||||
ArrayList<HarmonyActivity> activityList = new ArrayList<HarmonyActivity>();
|
||||
if(!validHarmony)
|
||||
return null;
|
||||
while(keys.hasNext()) {
|
||||
String key = keys.next();
|
||||
Activity theActivity = hubs.get(key).getMyHarmony().getCurrentActivity();
|
||||
HarmonyActivity anActivity = new HarmonyActivity();
|
||||
anActivity.setActivity(theActivity);
|
||||
anActivity.setHub(key);
|
||||
activityList.add(anActivity);
|
||||
}
|
||||
return activityList;
|
||||
}
|
||||
|
||||
public List<HarmonyDevice> getDevices() {
|
||||
Iterator<String> keys = hubs.keySet().iterator();
|
||||
ArrayList<HarmonyDevice> deviceList = new ArrayList<HarmonyDevice>();
|
||||
if(!validHarmony)
|
||||
if (!validHarmony)
|
||||
return null;
|
||||
while(keys.hasNext()) {
|
||||
while (keys.hasNext()) {
|
||||
String key = keys.next();
|
||||
Iterator<Device> devices = hubs.get(key).getMyHarmony().getDevices().iterator();
|
||||
while(devices.hasNext()) {
|
||||
HarmonyDevice aDevice = new HarmonyDevice();
|
||||
aDevice.setDevice(devices.next());
|
||||
aDevice.setHub(key);
|
||||
deviceList.add(aDevice);
|
||||
if (devices == null) {
|
||||
resetHub(hubs.get(key).getMyHarmony());
|
||||
devices = hubs.get(key).getMyHarmony().getDevices().iterator();
|
||||
if (devices == null) {
|
||||
if (resetHub(hubs.get(key).getMyHarmony())) {
|
||||
devices = hubs.get(key).getMyHarmony().getDevices().iterator();
|
||||
if (devices == null) {
|
||||
log.error("Could not get communication restored with hub: " + key
|
||||
+ ", please restart...");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (devices != null) {
|
||||
while (devices.hasNext()) {
|
||||
HarmonyDevice aDevice = new HarmonyDevice();
|
||||
aDevice.setDevice(devices.next());
|
||||
aDevice.setHub(key);
|
||||
deviceList.add(aDevice);
|
||||
}
|
||||
}
|
||||
}
|
||||
return deviceList;
|
||||
@@ -135,36 +180,47 @@ public class HarmonyHome implements Home {
|
||||
|
||||
@Override
|
||||
public String deviceHandler(CallItem anItem, MultiCommandUtil aMultiUtil, String lightId, int intensity,
|
||||
Integer targetBri,Integer targetBriInc, ColorData colorData, DeviceDescriptor device, String body) {
|
||||
Integer targetBri, Integer targetBriInc, ColorData colorData, DeviceDescriptor device, String body) {
|
||||
String responseString = null;
|
||||
log.debug("executing HUE api request to change " + anItem.getType() + " to Harmony: " + device.getName());
|
||||
if(!validHarmony) {
|
||||
if (!validHarmony) {
|
||||
log.warn("Should not get here, no harmony configured");
|
||||
responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
|
||||
+ "\",\"description\": \"Should not get here, no harmony configured\", \"parameter\": \"/lights/"
|
||||
+ lightId + "state\"}}]";
|
||||
+ lightId + "/state\"}}]";
|
||||
} else {
|
||||
if(anItem.getType().trim().equalsIgnoreCase(DeviceMapTypes.HARMONY_ACTIVITY[DeviceMapTypes.typeIndex]))
|
||||
{
|
||||
if (anItem.getType().trim().equalsIgnoreCase(DeviceMapTypes.HARMONY_ACTIVITY[DeviceMapTypes.typeIndex])) {
|
||||
RunActivity anActivity = null;
|
||||
if(anItem.getItem().isJsonObject())
|
||||
if (anItem.getItem().isJsonObject())
|
||||
anActivity = aGsonHandler.fromJson(anItem.getItem(), RunActivity.class);
|
||||
else
|
||||
anActivity = aGsonHandler.fromJson(anItem.getItem().getAsString(), RunActivity.class);
|
||||
if(anActivity.getHub() == null || anActivity.getHub().isEmpty())
|
||||
anActivity = aGsonHandler.fromJson(anItem.getItem().getAsString().replaceAll("^\"|\"$", ""), RunActivity.class);
|
||||
if (anActivity.getHub() == null || anActivity.getHub().isEmpty())
|
||||
anActivity.setHub(device.getTargetDevice());
|
||||
HarmonyHandler myHarmony = getHarmonyHandler(anActivity.getHub());
|
||||
if (myHarmony == null) {
|
||||
log.warn("Should not get here, no harmony hub available");
|
||||
responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
|
||||
+ "\",\"description\": \"Should not get here, no harmony hub available\", \"parameter\": \"/lights/"
|
||||
+ lightId + "state\"}}]";
|
||||
+ lightId + "/state\"}}]";
|
||||
} else {
|
||||
myHarmony.startActivity(anActivity);
|
||||
if (!myHarmony.startActivity(anActivity)) {
|
||||
if (resetHub(myHarmony)) {
|
||||
myHarmony = getHarmonyHandler(anActivity.getHub());
|
||||
if (!myHarmony.startActivity(anActivity)) {
|
||||
log.error("Could not get communication restored with hub: " + anActivity.getHub()
|
||||
+ ", please restart...");
|
||||
responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
|
||||
+ "\",\"description\": \"Could not communicate with harmony\", \"parameter\": \"/lights/"
|
||||
+ lightId + "/state\"}}]";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if(anItem.getType().trim().equalsIgnoreCase(DeviceMapTypes.HARMONY_BUTTON[DeviceMapTypes.typeIndex])) {
|
||||
} else if (anItem.getType().trim()
|
||||
.equalsIgnoreCase(DeviceMapTypes.HARMONY_BUTTON[DeviceMapTypes.typeIndex])) {
|
||||
String url = null;
|
||||
if(anItem.getItem().isJsonObject() || anItem.getItem().isJsonArray()) {
|
||||
if (anItem.getItem().isJsonObject() || anItem.getItem().isJsonArray()) {
|
||||
url = aGsonHandler.toJson(anItem.getItem());
|
||||
} else
|
||||
url = anItem.getItem().getAsString();
|
||||
@@ -172,35 +228,50 @@ public class HarmonyHome implements Home {
|
||||
if (url.substring(0, 1).equalsIgnoreCase("{")) {
|
||||
url = "[" + url + "]";
|
||||
}
|
||||
|
||||
|
||||
url = BrightnessDecode.calculateReplaceIntensityValue(url, intensity, targetBri, targetBriInc, false);
|
||||
ButtonPress[] deviceButtons = aGsonHandler.fromJson(url, ButtonPress[].class);
|
||||
Integer theCount = 1;
|
||||
for(int z = 0; z < deviceButtons.length; z++) {
|
||||
if(deviceButtons[z].getCount() != null && deviceButtons[z].getCount() > 0)
|
||||
theCount = deviceButtons[z].getCount();
|
||||
for(int y = 0; y < theCount; y++) {
|
||||
if( y > 0 || z > 0) {
|
||||
try {
|
||||
Thread.sleep(aMultiUtil.getTheDelay());
|
||||
} catch (InterruptedException e) {
|
||||
// ignore
|
||||
Integer theCount = 1;
|
||||
for (int z = 0; z < deviceButtons.length; z++) {
|
||||
if (deviceButtons[z].getCount() != null && deviceButtons[z].getCount() > 0)
|
||||
theCount = deviceButtons[z].getCount();
|
||||
for (int y = 0; y < theCount; y++) {
|
||||
if (y > 0 || z > 0) {
|
||||
try {
|
||||
Thread.sleep(aMultiUtil.getTheDelay());
|
||||
} catch (InterruptedException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
if (anItem.getDelay() != null && anItem.getDelay() > 0)
|
||||
aMultiUtil.setTheDelay(anItem.getDelay());
|
||||
else
|
||||
aMultiUtil.setTheDelay(aMultiUtil.getDelayDefault());
|
||||
log.debug("pressing button: " + deviceButtons[z].getDevice() + " - "
|
||||
+ deviceButtons[z].getButton() + " with pressTime of: "
|
||||
+ deviceButtons[z].getPressTime() + " - iteration: " + String.valueOf(z) + " - count: "
|
||||
+ String.valueOf(y));
|
||||
if (deviceButtons[z].getHub() == null || deviceButtons[z].getHub().isEmpty())
|
||||
deviceButtons[z].setHub(device.getTargetDevice());
|
||||
HarmonyHandler myHarmony = getHarmonyHandler(deviceButtons[z].getHub());
|
||||
if (myHarmony == null)
|
||||
log.warn("Button Press - Should not get here, no harmony hub available");
|
||||
else{
|
||||
if (!myHarmony.pressButton(deviceButtons[z])) {
|
||||
if (resetHub(myHarmony)) {
|
||||
myHarmony = getHarmonyHandler(deviceButtons[z].getHub());
|
||||
if (!myHarmony.pressButton(deviceButtons[z])) {
|
||||
log.error("Could not get communication restored with hub: " + deviceButtons[z].getHub()
|
||||
+ ", please restart...");
|
||||
responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
|
||||
+ "\",\"description\": \"Could not communicate with harmony\", \"parameter\": \"/lights/"
|
||||
+ lightId + "/state\"}}]";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (anItem.getDelay() != null && anItem.getDelay() > 0)
|
||||
aMultiUtil.setTheDelay(anItem.getDelay());
|
||||
else
|
||||
aMultiUtil.setTheDelay(aMultiUtil.getDelayDefault());
|
||||
log.debug("pressing button: " + deviceButtons[z].getDevice() + " - " + deviceButtons[z].getButton() + " with pressTime of: " + deviceButtons[z].getPressTime() + " - iteration: " + String.valueOf(z) + " - count: " + String.valueOf(y));
|
||||
if(deviceButtons[z].getHub() == null || deviceButtons[z].getHub().isEmpty())
|
||||
deviceButtons[z].setHub(device.getTargetDevice());
|
||||
HarmonyHandler myHarmony = getHarmonyHandler(deviceButtons[z].getHub());
|
||||
if (myHarmony == null)
|
||||
log.warn("Button Press - Should not get here, no harmony hub available");
|
||||
else
|
||||
myHarmony.pressButton(deviceButtons[z]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return responseString;
|
||||
@@ -208,15 +279,14 @@ public class HarmonyHome implements Home {
|
||||
|
||||
@Override
|
||||
public Home createHome(BridgeSettings bridgeSettings) {
|
||||
isDevMode = Boolean.parseBoolean(System.getProperty("dev.mode", "false"));
|
||||
validHarmony = bridgeSettings.getBridgeSettingsDescriptor().isValidHarmony();
|
||||
log.info("Harmony Home created." + (validHarmony ? "" : " No Harmony devices configured.") + (isDevMode ? " DevMode is set." : ""));
|
||||
if(validHarmony || isDevMode) {
|
||||
isDevMode = Boolean.parseBoolean(System.getProperty("dev.mode", "false"));
|
||||
validHarmony = bridgeSettings.getBridgeSettingsDescriptor().isValidHarmony();
|
||||
log.info("Harmony Home created." + (validHarmony ? "" : " No Harmony devices configured.")
|
||||
+ (isDevMode ? " DevMode is set." : ""));
|
||||
if (validHarmony || isDevMode) {
|
||||
hubs = new HashMap<String, HarmonyServer>();
|
||||
aGsonHandler =
|
||||
new GsonBuilder()
|
||||
.create();
|
||||
if(isDevMode) {
|
||||
aGsonHandler = new GsonBuilder().create();
|
||||
if (isDevMode) {
|
||||
NamedIP devModeIp = new NamedIP();
|
||||
devModeIp.setIp("10.10.10.10");
|
||||
devModeIp.setName("devMode");
|
||||
@@ -226,19 +296,21 @@ public class HarmonyHome implements Home {
|
||||
thedevList.setDevices(theList);
|
||||
bridgeSettings.getBridgeSettingsDescriptor().setHarmonyAddress(thedevList);
|
||||
}
|
||||
Iterator<NamedIP> theList = bridgeSettings.getBridgeSettingsDescriptor().getHarmonyAddress().getDevices().iterator();
|
||||
while(theList.hasNext() && validHarmony) {
|
||||
Iterator<NamedIP> theList = bridgeSettings.getBridgeSettingsDescriptor().getHarmonyAddress().getDevices()
|
||||
.iterator();
|
||||
while (theList.hasNext() && validHarmony) {
|
||||
NamedIP aHub = theList.next();
|
||||
boolean loopControl = true;
|
||||
int retryCount = 0;
|
||||
while(loopControl) {
|
||||
while (loopControl) {
|
||||
try {
|
||||
hubs.put(aHub.getName(), HarmonyServer.setup(bridgeSettings.getBridgeSettingsDescriptor(), isDevMode, aHub));
|
||||
loopControl = false;
|
||||
hubs.put(aHub.getName(), HarmonyServer.setup(isDevMode, aHub));
|
||||
loopControl = false;
|
||||
} catch (Exception e) {
|
||||
if(retryCount > 3) {
|
||||
log.error("Cannot get harmony client (" + aHub.getName() + ") setup, Exiting with message: " + e.getMessage(), e);
|
||||
loopControl = false;
|
||||
if (retryCount > 3) {
|
||||
log.error("Cannot get harmony client (" + aHub.getName() + ") setup, Exiting with message: "
|
||||
+ e.getMessage(), e);
|
||||
loopControl = false;
|
||||
} else {
|
||||
try {
|
||||
Thread.sleep(2000);
|
||||
@@ -246,27 +318,52 @@ public class HarmonyHome implements Home {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
retryCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(hubs.isEmpty())
|
||||
if (hubs.isEmpty())
|
||||
validHarmony = false;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
private boolean resetHub(HarmonyHandler aHarmony) {
|
||||
boolean resetSuccess = false;
|
||||
isDevMode = Boolean.parseBoolean(System.getProperty("dev.mode", "false"));
|
||||
NamedIP resetIp = aHarmony.getMyNameAndIP();
|
||||
log.info("Resetting harmony hub due to communication errror: " + resetIp.getName());
|
||||
if (!isDevMode) {
|
||||
try {
|
||||
hubs.remove(resetIp.getName());
|
||||
aHarmony.shutdown();
|
||||
hubs.put(resetIp.getName(), HarmonyServer.setup(isDevMode, resetIp));
|
||||
resetSuccess = true;
|
||||
} catch (Exception e) {
|
||||
log.error("Cannot reset harmony client (" + resetIp.getName() + "), Exiting with message: "
|
||||
+ e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
return resetSuccess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getItems(String type) {
|
||||
if(validHarmony) {
|
||||
if(type.equalsIgnoreCase(DeviceMapTypes.HARMONY_ACTIVITY[DeviceMapTypes.typeIndex]))
|
||||
if (validHarmony) {
|
||||
if (type.equalsIgnoreCase(DeviceMapTypes.HARMONY_ACTIVITY[DeviceMapTypes.typeIndex]))
|
||||
return getActivities();
|
||||
if(type.equalsIgnoreCase(DeviceMapTypes.HARMONY_BUTTON[DeviceMapTypes.typeIndex]))
|
||||
if (type.equalsIgnoreCase(DeviceMapTypes.HARMONY_BUTTON[DeviceMapTypes.typeIndex]))
|
||||
return getDevices();
|
||||
if(type.equalsIgnoreCase("current_activity"))
|
||||
if (type.equalsIgnoreCase("current_activity"))
|
||||
return getCurrentActivities();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh() {
|
||||
// noop
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ import org.apache.http.client.methods.HttpGet;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.bwssystems.HABridge.BridgeSettingsDescriptor;
|
||||
import com.bwssystems.HABridge.NamedIP;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
@@ -50,11 +49,10 @@ public class HarmonyServer {
|
||||
}
|
||||
|
||||
public static HarmonyServer setup(
|
||||
BridgeSettingsDescriptor bridgeSettings,
|
||||
Boolean harmonyDevMode,
|
||||
NamedIP theHarmonyAddress
|
||||
) throws Exception {
|
||||
if (!bridgeSettings.isValidHarmony() && harmonyDevMode) {
|
||||
if (harmonyDevMode) {
|
||||
return new HarmonyServer(theHarmonyAddress);
|
||||
}
|
||||
Injector injector = null;
|
||||
@@ -65,11 +63,11 @@ public class HarmonyServer {
|
||||
if (!harmonyDevMode) {
|
||||
injector.injectMembers(mainObject);
|
||||
}
|
||||
mainObject.execute(bridgeSettings, harmonyDevMode);
|
||||
mainObject.execute(harmonyDevMode);
|
||||
return mainObject;
|
||||
}
|
||||
|
||||
private void execute(BridgeSettingsDescriptor mySettings, Boolean harmonyDevMode) throws Exception {
|
||||
private void execute(Boolean harmonyDevMode) throws Exception {
|
||||
Boolean noopCalls = Boolean.parseBoolean(System.getProperty("noop.calls", "false"));
|
||||
isDevMode = harmonyDevMode;
|
||||
String modeString = "";
|
||||
@@ -110,7 +108,7 @@ public class HarmonyServer {
|
||||
});
|
||||
harmonyClient.connect(myNameAndIP.getIp());
|
||||
}
|
||||
myHarmony = new HarmonyHandler(harmonyClient, noopCalls, devResponse);
|
||||
myHarmony = new HarmonyHandler(harmonyClient, noopCalls, devResponse, myNameAndIP);
|
||||
}
|
||||
|
||||
public HarmonyHandler getMyHarmony() {
|
||||
|
||||
@@ -98,7 +98,7 @@ public class HassHome implements Home {
|
||||
|
||||
private Boolean addHassDevices(List<HassDevice> theDeviceList, List<State> theSourceList, String theKey) {
|
||||
if(!validHass)
|
||||
return null;
|
||||
return false;
|
||||
Iterator<State> devices = theSourceList.iterator();
|
||||
while(devices.hasNext()) {
|
||||
State theDevice = devices.next();
|
||||
@@ -117,6 +117,11 @@ public class HassHome implements Home {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh() {
|
||||
// noop
|
||||
}
|
||||
|
||||
@Override
|
||||
public String deviceHandler(CallItem anItem, MultiCommandUtil aMultiUtil, String lightId, int intensity,
|
||||
Integer targetBri,Integer targetBriInc, ColorData colorData, DeviceDescriptor device, String body) {
|
||||
@@ -126,14 +131,14 @@ public class HassHome implements Home {
|
||||
log.warn("Should not get here, no HomeAssistant clients configured");
|
||||
theReturn = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
|
||||
+ "\",\"description\": \"Should not get here, no HomeAssistants configured\", \"parameter\": \"/lights/"
|
||||
+ lightId + "state\"}}]";
|
||||
+ lightId + "/state\"}}]";
|
||||
|
||||
} else {
|
||||
HassCommand hassCommand = null;
|
||||
if(anItem.getItem().isJsonObject())
|
||||
hassCommand = aGsonHandler.fromJson(anItem.getItem(), HassCommand.class);
|
||||
else
|
||||
hassCommand = aGsonHandler.fromJson(anItem.getItem().getAsString(), HassCommand.class);
|
||||
hassCommand = aGsonHandler.fromJson(anItem.getItem().getAsString().replaceAll("^\"|\"$", ""), HassCommand.class);
|
||||
hassCommand.setBri(BrightnessDecode.replaceIntensityValue(hassCommand.getBri(),
|
||||
BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc), false));
|
||||
HomeAssistant homeAssistant = getHomeAssistant(hassCommand.getHassName());
|
||||
@@ -141,7 +146,7 @@ public class HassHome implements Home {
|
||||
log.warn("Should not get here, no HomeAssistants available");
|
||||
theReturn = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
|
||||
+ "\",\"description\": \"Should not get here, no HiomeAssistant clients available\", \"parameter\": \"/lights/"
|
||||
+ lightId + "state\"}}]";
|
||||
+ lightId + "/state\"}}]";
|
||||
} else {
|
||||
log.debug("calling HomeAssistant: " + hassCommand.getHassName() + " - "
|
||||
+ hassCommand.getEntityId() + " - " + hassCommand.getState() + " - " + hassCommand.getBri());
|
||||
|
||||
@@ -38,12 +38,8 @@ public class HomeAssistant {
|
||||
log.debug("calling HomeAssistant: " + aCommand.getHassName() + " - "
|
||||
+ aCommand.getEntityId() + " - " + aCommand.getState() + " - " + aCommand.getBri());
|
||||
String aUrl = null;
|
||||
if(hassAddress.getSecure() != null && hassAddress.getSecure())
|
||||
aUrl = "https";
|
||||
else
|
||||
aUrl = "http";
|
||||
String domain = aCommand.getEntityId().substring(0, aCommand.getEntityId().indexOf("."));
|
||||
aUrl = aUrl + "://" + hassAddress.getIp() + ":" + hassAddress.getPort() + "/api/services/";
|
||||
aUrl = hassAddress.getHttpPreamble() + "/api/services/";
|
||||
if(domain.equals("group"))
|
||||
aUrl = aUrl + "homeassistant";
|
||||
else
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.bwssystems.HABridge.plugins.homegenie;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class HomeGenieCommand {
|
||||
@SerializedName("moduleType")
|
||||
@Expose
|
||||
private String moduleType;
|
||||
@SerializedName("deviceId")
|
||||
@Expose
|
||||
private String deviceId;
|
||||
@SerializedName("command")
|
||||
@Expose
|
||||
private HomeGenieCommandDetail command;
|
||||
|
||||
public String getModuleType() {
|
||||
return moduleType;
|
||||
}
|
||||
|
||||
public void setModuleType(String moduleType) {
|
||||
this.moduleType = moduleType;
|
||||
}
|
||||
|
||||
public String getDeviceId() {
|
||||
return deviceId;
|
||||
}
|
||||
|
||||
public void setDeviceId(String deviceId) {
|
||||
this.deviceId = deviceId;
|
||||
}
|
||||
|
||||
public HomeGenieCommandDetail getCommand() {
|
||||
return command;
|
||||
}
|
||||
|
||||
public void setCommand(HomeGenieCommandDetail command) {
|
||||
this.command = command;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.bwssystems.HABridge.plugins.homegenie;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class HomeGenieCommandDetail {
|
||||
@SerializedName("command")
|
||||
@Expose
|
||||
private String command;
|
||||
@SerializedName("level")
|
||||
@Expose
|
||||
private String level;
|
||||
@SerializedName("color")
|
||||
@Expose
|
||||
private String color;
|
||||
|
||||
public String getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public void setLevel(String level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
public String getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public void setColor(String color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public String getCommand() {
|
||||
return command;
|
||||
}
|
||||
|
||||
public void setCommand(String command) {
|
||||
this.command = command;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.bwssystems.HABridge.plugins.homegenie;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class HomeGenieDevice {
|
||||
@SerializedName("gatewayName")
|
||||
@Expose
|
||||
private String gatewayName;
|
||||
@SerializedName("deviceDetail")
|
||||
@Expose
|
||||
private Module deviceDetail;
|
||||
|
||||
public String getGatewayName() {
|
||||
return gatewayName;
|
||||
}
|
||||
|
||||
public void setGatewayName(String gatewayName) {
|
||||
this.gatewayName = gatewayName;
|
||||
}
|
||||
|
||||
public Module getDeviceDetail() {
|
||||
return deviceDetail;
|
||||
}
|
||||
|
||||
public void setDeviceDetail(Module deviceDetail) {
|
||||
this.deviceDetail = deviceDetail;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
package com.bwssystems.HABridge.plugins.homegenie;
|
||||
|
||||
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.BridgeSettings;
|
||||
import com.bwssystems.HABridge.Home;
|
||||
import com.bwssystems.HABridge.NamedIP;
|
||||
import com.bwssystems.HABridge.api.CallItem;
|
||||
import com.bwssystems.HABridge.api.hue.HueError;
|
||||
import com.bwssystems.HABridge.api.hue.HueErrorResponse;
|
||||
import com.bwssystems.HABridge.dao.DeviceDescriptor;
|
||||
import com.bwssystems.HABridge.hue.BrightnessDecode;
|
||||
import com.bwssystems.HABridge.hue.ColorData;
|
||||
import com.bwssystems.HABridge.hue.ColorDecode;
|
||||
import com.bwssystems.HABridge.hue.DeviceDataDecode;
|
||||
import com.bwssystems.HABridge.hue.MultiCommandUtil;
|
||||
import com.bwssystems.HABridge.hue.TimeDecode;
|
||||
import com.bwssystems.HABridge.plugins.http.HTTPHandler;
|
||||
import com.bwssystems.HABridge.plugins.http.HTTPHome;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
public class HomeGenieHome implements Home {
|
||||
private static final Logger log = LoggerFactory.getLogger(HomeGenieHome.class);
|
||||
private Map<String, HomeGenieInstance> homegenieMap;
|
||||
private Boolean validHomeGenie;
|
||||
private HTTPHandler httpClient;
|
||||
private boolean closed;
|
||||
|
||||
public HomeGenieHome(BridgeSettings bridgeSettings) {
|
||||
super();
|
||||
closed = true;
|
||||
createHome(bridgeSettings);
|
||||
closed = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String deviceHandler(CallItem anItem, MultiCommandUtil aMultiUtil, String lightId, int intensity,
|
||||
Integer targetBri, Integer targetBriInc, ColorData colorData, DeviceDescriptor device, String body) {
|
||||
|
||||
String theUrl = anItem.getItem().getAsString().replaceAll("^\"|\"$", "");
|
||||
String responseString = null;
|
||||
|
||||
if (theUrl != null && !theUrl.isEmpty()) {
|
||||
String anUrl = BrightnessDecode.calculateReplaceIntensityValue(theUrl, intensity, targetBri, targetBriInc,
|
||||
false);
|
||||
if (colorData != null) {
|
||||
anUrl = ColorDecode.replaceColorData(anUrl, colorData,
|
||||
BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc), true);
|
||||
}
|
||||
anUrl = DeviceDataDecode.replaceDeviceData(anUrl, device);
|
||||
anUrl = TimeDecode.replaceTimeValue(anUrl);
|
||||
|
||||
anUrl = BrightnessDecode.calculateReplaceIntensityValue(anUrl, intensity, targetBri, targetBriInc, false);
|
||||
if (colorData != null) {
|
||||
anUrl = ColorDecode.replaceColorData(anUrl, colorData,
|
||||
BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc), false);
|
||||
}
|
||||
anUrl = DeviceDataDecode.replaceDeviceData(anUrl, device);
|
||||
anUrl = TimeDecode.replaceTimeValue(anUrl);
|
||||
|
||||
HomeGenieCommand theCommand = null;
|
||||
try {
|
||||
theCommand = new Gson().fromJson(anUrl, HomeGenieCommand.class);
|
||||
} catch (Exception e) {
|
||||
log.warn("Cannot parse command to HomeGenie <<<" + theUrl + ">>>", e);
|
||||
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
|
||||
"Error on calling url to change device state", "/lights/" + lightId + "/state", null, null)
|
||||
.getTheErrors(), HueError[].class);
|
||||
return responseString;
|
||||
}
|
||||
|
||||
HomeGenieInstance theHandler = homegenieMap.get(device.getTargetDevice());
|
||||
if (theHandler != null) {
|
||||
try {
|
||||
boolean success = theHandler.callCommand(theCommand.getDeviceId(), theCommand.getModuleType(), theCommand.getCommand(), httpClient);
|
||||
if (!success) {
|
||||
log.warn("Comand had error to HomeGenie");
|
||||
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
|
||||
"Error on calling url to change device state", "/lights/" + lightId + "/state", null,
|
||||
null).getTheErrors(), HueError[].class);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("Cannot send comand to HomeGenie", e);
|
||||
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
|
||||
"Error on calling url to change device state", "/lights/" + lightId + "/state", null, null)
|
||||
.getTheErrors(), HueError[].class);
|
||||
}
|
||||
} else {
|
||||
log.warn("HomeGenie Call could not complete, no address found: " + theUrl);
|
||||
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
|
||||
"Error on calling url to change device state", "/lights/" + lightId + "/state", null, null)
|
||||
.getTheErrors(), HueError[].class);
|
||||
}
|
||||
} else {
|
||||
log.warn(
|
||||
"HomeGenie Call to be presented as http(s)://<ip_address>(:<port>)/payload, format of request unknown: "
|
||||
+ theUrl);
|
||||
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
|
||||
"Error on calling url to change device state", "/lights/" + lightId + "/state", null, null)
|
||||
.getTheErrors(), HueError[].class);
|
||||
}
|
||||
return responseString;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getItems(String type) {
|
||||
|
||||
if (!validHomeGenie)
|
||||
return null;
|
||||
log.debug("consolidating devices for HomeGenie");
|
||||
List<Module> theResponse = null;
|
||||
Iterator<String> keys = homegenieMap.keySet().iterator();
|
||||
List<HomeGenieDevice> deviceList = new ArrayList<HomeGenieDevice>();
|
||||
while (keys.hasNext()) {
|
||||
String key = keys.next();
|
||||
theResponse = homegenieMap.get(key).getDevices(httpClient);
|
||||
if (theResponse != null)
|
||||
addHomeGenieDevices(deviceList, theResponse, key);
|
||||
else {
|
||||
log.warn("Cannot get devices for HomeGenie with name: " + key + ", skipping this HomeGenie.");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return deviceList;
|
||||
}
|
||||
|
||||
private Boolean addHomeGenieDevices(List<HomeGenieDevice> theDeviceList, List<Module> theSourceList,
|
||||
String theKey) {
|
||||
Iterator<Module> hgModules = theSourceList.iterator();
|
||||
while (hgModules.hasNext()) {
|
||||
Module aModule = hgModules.next();
|
||||
HomeGenieDevice theDevice = new HomeGenieDevice();
|
||||
theDevice.setDeviceDetail(aModule);
|
||||
theDevice.setGatewayName(theKey);
|
||||
theDeviceList.add(theDevice);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Home createHome(BridgeSettings bridgeSettings) {
|
||||
homegenieMap = null;
|
||||
validHomeGenie = bridgeSettings.getBridgeSettingsDescriptor().isValidHomeGenie();
|
||||
log.info("HomeGenie Home created." + (validHomeGenie ? "" : " No HomeGenies configured."));
|
||||
if (validHomeGenie) {
|
||||
homegenieMap = new HashMap<String, HomeGenieInstance>();
|
||||
httpClient = HTTPHome.getHandler();
|
||||
Iterator<NamedIP> theList = bridgeSettings.getBridgeSettingsDescriptor().getHomegenieaddress().getDevices()
|
||||
.iterator();
|
||||
while (theList.hasNext() && validHomeGenie) {
|
||||
NamedIP aHomeGenie = theList.next();
|
||||
try {
|
||||
homegenieMap.put(aHomeGenie.getName(), new HomeGenieInstance(aHomeGenie, httpClient));
|
||||
} catch (Exception e) {
|
||||
log.error("Cannot get HomeGenie (" + aHomeGenie.getName() + ") setup, Exiting with message: "
|
||||
+ e.getMessage(), e);
|
||||
validHomeGenie = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeHome() {
|
||||
log.debug("Closing Home.");
|
||||
if (!closed && validHomeGenie) {
|
||||
log.debug("Home is already closed....");
|
||||
return;
|
||||
}
|
||||
|
||||
if (httpClient != null)
|
||||
httpClient.closeHandler();
|
||||
|
||||
homegenieMap = null;
|
||||
closed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh() {
|
||||
// noop
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package com.bwssystems.HABridge.plugins.homegenie;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.bwssystems.HABridge.NamedIP;
|
||||
import com.bwssystems.HABridge.plugins.http.HTTPHandler;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpPut;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class HomeGenieInstance {
|
||||
private static final Logger log = LoggerFactory.getLogger(HomeGenieInstance.class);
|
||||
private NamedIP homegenieIP;
|
||||
|
||||
public HomeGenieInstance(NamedIP theNamedIp, HTTPHandler httpClient) {
|
||||
homegenieIP = theNamedIp;
|
||||
}
|
||||
|
||||
public Boolean callCommand(String deviceId, String moduleType, HomeGenieCommandDetail commandData,
|
||||
HTTPHandler httpClient) {
|
||||
log.debug("calling HomeGenie: {}:{}{}{}", homegenieIP.getIp(), homegenieIP.getPort(), moduleType,
|
||||
commandData.getCommand());
|
||||
String aUrl = null;
|
||||
|
||||
aUrl = homegenieIP.getHttpPreamble() + "/api/" + moduleType + "/" + deviceId + "/" + commandData.getCommand();
|
||||
|
||||
String theLevel = commandData.getLevel();
|
||||
if (commandData.getCommand().contains("Level")) {
|
||||
if (theLevel != null && theLevel.length() > 0)
|
||||
aUrl = aUrl + "/" + theLevel;
|
||||
else
|
||||
aUrl = aUrl + "100";
|
||||
}
|
||||
|
||||
String theData = httpClient.doHttpRequest(aUrl, HttpPut.METHOD_NAME, "application/json", null, httpClient.addBasicAuthHeader(null, homegenieIP));
|
||||
log.debug("call Command return is: <<<{}>>>", theData);
|
||||
if (!theData.contains("OK"))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public List<Module> getDevices(HTTPHandler httpClient) {
|
||||
log.debug("calling HomeGenie: " + homegenieIP.getIp() + ":" + homegenieIP.getPort());
|
||||
List<Module> deviceList = null;
|
||||
Module[] hgModules;
|
||||
String theUrl = null;
|
||||
String theData;
|
||||
|
||||
theUrl = homegenieIP.getHttpPreamble() + "/api/HomeAutomation.HomeGenie/Config/Modules.List";
|
||||
|
||||
theData = httpClient.doHttpRequest(theUrl, HttpGet.METHOD_NAME, "application/json", null, httpClient.addBasicAuthHeader(null, homegenieIP));
|
||||
if (theData != null) {
|
||||
log.debug("GET HomeGenie Devices - data: " + theData);
|
||||
try {
|
||||
hgModules = new Gson().fromJson(theData, Module[].class);
|
||||
if (hgModules != null && hgModules.length > 0) {
|
||||
deviceList = new ArrayList<Module>();
|
||||
for (int i = 0; i < hgModules.length; i++) {
|
||||
if (hgModules[i].isSwitch() || hgModules[i].isDimmer())
|
||||
deviceList.add(hgModules[i]);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("Cannot get an devices for Homegenie {} Gson Parse Error.", homegenieIP.getName());
|
||||
}
|
||||
}
|
||||
return deviceList;
|
||||
}
|
||||
|
||||
public NamedIP getHomegenieIP() {
|
||||
return homegenieIP;
|
||||
}
|
||||
|
||||
public void setHomegenieIP(NamedIP homegenieIP) {
|
||||
this.homegenieIP = homegenieIP;
|
||||
}
|
||||
|
||||
protected void closeClient() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
|
||||
package com.bwssystems.HABridge.plugins.homegenie;
|
||||
|
||||
// import java.util.List;
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class Module {
|
||||
|
||||
@SerializedName("Name")
|
||||
@Expose
|
||||
private String name;
|
||||
@SerializedName("Description")
|
||||
@Expose
|
||||
private String description;
|
||||
@SerializedName("DeviceType")
|
||||
@Expose
|
||||
private String deviceType;
|
||||
@SerializedName("Domain")
|
||||
@Expose
|
||||
private String domain;
|
||||
@SerializedName("Address")
|
||||
@Expose
|
||||
private String address;
|
||||
/*
|
||||
@SerializedName("Properties")
|
||||
@Expose
|
||||
private List<Property> properties = null;
|
||||
*/
|
||||
@SerializedName("RoutingNode")
|
||||
@Expose
|
||||
private String routingNode;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getDeviceType() {
|
||||
return deviceType;
|
||||
}
|
||||
|
||||
public void setDeviceType(String deviceType) {
|
||||
this.deviceType = deviceType;
|
||||
}
|
||||
|
||||
public String getDomain() {
|
||||
return domain;
|
||||
}
|
||||
|
||||
public void setDomain(String domain) {
|
||||
this.domain = domain;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
/*
|
||||
public List<Property> getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
public void setProperties(List<Property> properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
*/
|
||||
public String getRoutingNode() {
|
||||
return routingNode;
|
||||
}
|
||||
|
||||
public void setRoutingNode(String routingNode) {
|
||||
this.routingNode = routingNode;
|
||||
}
|
||||
|
||||
public boolean isSwitch() {
|
||||
return isDeviceType("Switch");
|
||||
}
|
||||
|
||||
public boolean isDimmer() {
|
||||
return isDeviceType("Dimmer");
|
||||
}
|
||||
|
||||
private boolean isDeviceType(String theType) {
|
||||
if(deviceType.equals(theType)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
|
||||
package com.bwssystems.HABridge.plugins.homegenie;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class Property {
|
||||
|
||||
@SerializedName("Name")
|
||||
@Expose
|
||||
private String name;
|
||||
@SerializedName("Value")
|
||||
@Expose
|
||||
private String value;
|
||||
@SerializedName("Description")
|
||||
@Expose
|
||||
private String description;
|
||||
@SerializedName("FieldType")
|
||||
@Expose
|
||||
private String fieldType;
|
||||
@SerializedName("UpdateTime")
|
||||
@Expose
|
||||
private String updateTime;
|
||||
@SerializedName("NeedsUpdate")
|
||||
@Expose
|
||||
private Boolean needsUpdate;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getFieldType() {
|
||||
return fieldType;
|
||||
}
|
||||
|
||||
public void setFieldType(String fieldType) {
|
||||
this.fieldType = fieldType;
|
||||
}
|
||||
|
||||
public String getUpdateTime() {
|
||||
return updateTime;
|
||||
}
|
||||
|
||||
public void setUpdateTime(String updateTime) {
|
||||
this.updateTime = updateTime;
|
||||
}
|
||||
|
||||
public Boolean getNeedsUpdate() {
|
||||
return needsUpdate;
|
||||
}
|
||||
|
||||
public void setNeedsUpdate(Boolean needsUpdate) {
|
||||
this.needsUpdate = needsUpdate;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -49,20 +49,20 @@ public class HomeWizardHome implements Home {
|
||||
log.warn("Should not get here, no HomeWizard smart plug available");
|
||||
responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
|
||||
+ "\",\"description\": \"Should not get here, no HomeWizard smart plug available\", \"parameter\": \"/lights/"
|
||||
+ lightId + "state\"}}]";
|
||||
+ lightId + "/state\"}}]";
|
||||
} else {
|
||||
|
||||
if (anItem.getType() != null && anItem.getType().trim().equalsIgnoreCase(DeviceMapTypes.HOMEWIZARD_DEVICE[DeviceMapTypes.typeIndex])) {
|
||||
|
||||
log.debug("Executing HUE api request to change activity to HomeWizard smart plug: " + anItem.getItem().toString());
|
||||
String jsonToPost = anItem.getItem().toString();
|
||||
String jsonToPost = anItem.getItem().getAsString().replaceAll("^\"|\"$", "");
|
||||
log.debug("Executing HUE api request to change activity to HomeWizard smart plug: {}", jsonToPost);
|
||||
|
||||
HomeWizzardSmartPlugInfo homeWizzardHandler = getHomeWizzardHandler(device.getTargetDevice());
|
||||
if(homeWizzardHandler == null) {
|
||||
log.warn("Should not get here, no HomeWizard smart plug configured");
|
||||
responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
|
||||
+ "\",\"description\": \"Should not get here, no HomeWizard smart plug configured\", \"parameter\": \"/lights/"
|
||||
+ lightId + "state\"}}]";
|
||||
+ lightId + "/state\"}}]";
|
||||
} else {
|
||||
try {
|
||||
homeWizzardHandler.execApply(jsonToPost);
|
||||
@@ -70,7 +70,7 @@ public class HomeWizardHome implements Home {
|
||||
|
||||
log.warn("Error posting request to HomeWizard smart plug");
|
||||
responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
|
||||
+ "\",\"description\": \"Error posting request to HomeWizard smart plug\", \"parameter\": \"/lights/" + lightId + "state\"}}]";
|
||||
+ "\",\"description\": \"Error posting request to HomeWizard smart plug\", \"parameter\": \"/lights/" + lightId + "/state\"}}]";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -85,7 +85,7 @@ public class HomeWizardHome implements Home {
|
||||
|
||||
public List<HomeWizardSmartPlugDevice> getDevices() {
|
||||
|
||||
log.debug("consolidating devices for plug gateways");
|
||||
log.debug("consolidating devices for HomeWizard plug gateways");
|
||||
Iterator<String> keys = plugGateways.keySet().iterator();
|
||||
ArrayList<HomeWizardSmartPlugDevice> deviceList = new ArrayList<>();
|
||||
|
||||
@@ -147,4 +147,9 @@ public class HomeWizardHome implements Home {
|
||||
plugGateways = null;
|
||||
closed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh() {
|
||||
// noop
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,8 +9,6 @@ import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -19,9 +17,7 @@ import com.bwssystems.HABridge.NamedIP;
|
||||
import com.bwssystems.HABridge.plugins.homewizard.json.Device;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import us.monoid.json.JSONException;
|
||||
import us.monoid.json.JSONObject;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
/**
|
||||
* Control HomeWizard devices over HomeWizard Cloud
|
||||
@@ -48,7 +44,7 @@ public class HomeWizzardSmartPlugInfo {
|
||||
|
||||
super();
|
||||
|
||||
cloudAuth = "Basic " + new String(Base64.encodeBase64((gateway.getUsername() + ":" + DigestUtils.sha1Hex(gateway.getPassword())).getBytes()));
|
||||
cloudAuth = "Basic " + gateway.getUserPass64();
|
||||
cloudPlugName = name;
|
||||
gson = new Gson();
|
||||
}
|
||||
@@ -75,10 +71,12 @@ public class HomeWizzardSmartPlugInfo {
|
||||
br.close();
|
||||
|
||||
// Get session id from result JSON
|
||||
JSONObject json = new JSONObject(buffer.toString());
|
||||
cloudSessionId = json.get("session").toString();
|
||||
JsonParser parser = new JsonParser();
|
||||
JsonObject json = parser.parse(buffer.toString()).getAsJsonObject();
|
||||
|
||||
cloudSessionId = json.get("session").getAsString();
|
||||
}
|
||||
catch(IOException | JSONException e)
|
||||
catch(Exception e)
|
||||
{
|
||||
log.warn("Error while login to cloud service ", e);
|
||||
return false;
|
||||
@@ -191,8 +189,9 @@ public class HomeWizzardSmartPlugInfo {
|
||||
try {
|
||||
|
||||
String result = requestJson(EMPTY_STRING);
|
||||
JSONObject resultJson = new JSONObject(result);
|
||||
cloudPlugId = resultJson.getString("id");
|
||||
JsonParser parser = new JsonParser();
|
||||
JsonObject resultJson = parser.parse(result).getAsJsonObject();
|
||||
cloudPlugId = resultJson.get("id").getAsString();
|
||||
|
||||
String all_devices_json = resultJson.get("devices").toString();
|
||||
Device[] devices = gson.fromJson(all_devices_json, Device[].class);
|
||||
@@ -203,7 +202,7 @@ public class HomeWizzardSmartPlugInfo {
|
||||
homewizardDevices.add(mapDeviceToHomeWizardSmartPlugDevice(device));
|
||||
}
|
||||
}
|
||||
catch(JSONException e) {
|
||||
catch(Exception e) {
|
||||
log.warn("Error while get devices from cloud service ", e);
|
||||
}
|
||||
|
||||
@@ -211,12 +210,13 @@ public class HomeWizzardSmartPlugInfo {
|
||||
return homewizardDevices;
|
||||
}
|
||||
|
||||
public void execApply(String jsonToPost) throws JSONException, IOException {
|
||||
public void execApply(String jsonToPost) throws Exception {
|
||||
|
||||
// Extract
|
||||
JSONObject resultJson = new JSONObject(jsonToPost);
|
||||
String deviceId = resultJson.getString("deviceid");
|
||||
String action = resultJson.getString("action");
|
||||
JsonParser parser = new JsonParser();
|
||||
JsonObject resultJson = parser.parse(jsonToPost).getAsJsonObject();
|
||||
String deviceId = resultJson.get("deviceid").getAsString();
|
||||
String action = resultJson.get("action").getAsString();
|
||||
|
||||
// Check if we have an plug id stored
|
||||
if (StringUtils.isBlank(cloudPlugId)) {
|
||||
|
||||
@@ -17,31 +17,53 @@ import org.apache.http.util.EntityUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.bwssystems.HABridge.DeviceMapTypes;
|
||||
import com.bwssystems.HABridge.NamedIP;
|
||||
import com.bwssystems.HABridge.api.NameValue;
|
||||
|
||||
public class HTTPHandler {
|
||||
private static final Logger log = LoggerFactory.getLogger(HTTPHandler.class);
|
||||
|
||||
private String callType;
|
||||
|
||||
public HTTPHandler() {
|
||||
super();
|
||||
callType = null;
|
||||
}
|
||||
|
||||
public HTTPHandler(String type) {
|
||||
super();
|
||||
callType = type;
|
||||
}
|
||||
|
||||
// This function executes the url from the device repository against the
|
||||
// target as http or https as defined
|
||||
public String doHttpRequest(String url, String httpVerb, String contentType, String body, NameValue[] headers) {
|
||||
log.debug("doHttpRequest with url: " + url + " with http command: " + httpVerb + " with body: " + body);
|
||||
HttpUriRequest request = null;
|
||||
String theContent = null;
|
||||
URI theURI = null;
|
||||
boolean usingSSL = false;
|
||||
ContentType parsedContentType = null;
|
||||
StringEntity requestBody = null;
|
||||
|
||||
log.debug("doHttpRequest with url <<<" + url + ">>>, verb: " + httpVerb + ", contentType: " + contentType
|
||||
+ ", body <<<" + body + ">>>");
|
||||
if (headers != null && headers.length > 0) {
|
||||
for (int i = 0; i < headers.length; i++) {
|
||||
log.debug("header index " + i + " name: <<<" + headers[i].getName() + ">>>, value: <<<"
|
||||
+ headers[i].getValue() + ">>>");
|
||||
}
|
||||
}
|
||||
|
||||
if (contentType != null && !contentType.trim().isEmpty()) {
|
||||
parsedContentType = ContentType.parse(contentType);
|
||||
if (body != null && body.length() > 0)
|
||||
requestBody = new StringEntity(body, parsedContentType);
|
||||
}
|
||||
|
||||
if (url.startsWith("https:")) {
|
||||
usingSSL = true;
|
||||
}
|
||||
|
||||
try {
|
||||
theURI = new URI(url);
|
||||
} catch (URISyntaxException e1) {
|
||||
@@ -78,7 +100,11 @@ public class HTTPHandler {
|
||||
CloseableHttpResponse response = null;
|
||||
for (int retryCount = 0; retryCount < 2; retryCount++) {
|
||||
try {
|
||||
response = HttpClientPool.getClient().execute(request);
|
||||
if (usingSSL) {
|
||||
response = HttpClientPool.getSSLClient().execute(request);
|
||||
} else {
|
||||
response = HttpClientPool.getClient().execute(request);
|
||||
}
|
||||
log.debug((httpVerb == null ? "GET" : httpVerb) + " execute (" + retryCount + ") on URL responded: "
|
||||
+ response.getStatusLine().getStatusCode());
|
||||
if (response != null && response.getEntity() != null) {
|
||||
@@ -94,32 +120,44 @@ public class HTTPHandler {
|
||||
// ignore
|
||||
// content
|
||||
} catch (Exception e) {
|
||||
log.debug("Error ocurred in handling response entity after successful call, still responding success. "
|
||||
+ e.getMessage(), e);
|
||||
log.debug(
|
||||
"Error ocurred in handling response entity after successful call, still responding success. "
|
||||
+ e.getMessage(),
|
||||
e);
|
||||
}
|
||||
}
|
||||
if (response != null && response.getStatusLine().getStatusCode() >= 200 && response.getStatusLine().getStatusCode() < 300) {
|
||||
if (response != null && response.getStatusLine().getStatusCode() >= 200
|
||||
&& response.getStatusLine().getStatusCode() < 300) {
|
||||
if (theContent == null)
|
||||
theContent = "";
|
||||
log.debug("Successfull response - The http response is <<<" + theContent + ">>>");
|
||||
retryCount = 2;
|
||||
} else if (DeviceMapTypes.FHEM_DEVICE[DeviceMapTypes.typeIndex].equals(callType)
|
||||
&& response.getStatusLine().getStatusCode() == 302) {
|
||||
if (theContent == null)
|
||||
theContent = "";
|
||||
log.debug("Successfull response - The http response is <<<" + theContent + ">>>");
|
||||
retryCount = 2;
|
||||
} else if (response != null) {
|
||||
log.warn("HTTP response code was not an expected successful response of between 200 - 299, the code was: "
|
||||
+ response.getStatusLine());
|
||||
log.warn(
|
||||
"HTTP response code was not an expected successful response of between 200 - 299, the code was: "
|
||||
+ response.getStatusLine() + " with the content of <<<" + theContent + ">>>");
|
||||
if (response.getStatusLine().getStatusCode() == 504) {
|
||||
log.warn("HTTP response code was 504, retrying...");
|
||||
log.debug("The 504 error content is <<<" + theContent + ">>>");
|
||||
theContent = null;
|
||||
} else
|
||||
retryCount = 2;
|
||||
|
||||
theContent = null;
|
||||
}
|
||||
|
||||
|
||||
} catch (ClientProtocolException e) {
|
||||
log.warn("Client Protocol Exception received, retyring....");
|
||||
}catch (IOException e) {
|
||||
log.warn("Error calling out to HA gateway: IOException in log: " + e.getMessage());
|
||||
} catch (IOException e) {
|
||||
log.warn("Error calling out to HA gateway: IOException in log: " + e.getMessage(), e);
|
||||
retryCount = 2;
|
||||
}
|
||||
|
||||
if(retryCount < 2) {
|
||||
if (retryCount < 2) {
|
||||
theContent = null;
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
@@ -130,6 +168,40 @@ public class HTTPHandler {
|
||||
}
|
||||
return theContent;
|
||||
}
|
||||
|
||||
public NameValue[] addBasicAuthHeader(NameValue[] theHeaders, NamedIP theTarget) {
|
||||
NameValue[] headers = null;
|
||||
int index = 0;
|
||||
String encodedLogin = theTarget.getUserPass64();
|
||||
if (encodedLogin != null && !encodedLogin.trim().isEmpty()) {
|
||||
if (theHeaders != null && theHeaders.length > 0) {
|
||||
headers = new NameValue[theHeaders.length + 1];
|
||||
for(int i = 0; i < theHeaders.length; i++) {
|
||||
headers[i] = theHeaders[i];
|
||||
}
|
||||
index = theHeaders.length;
|
||||
} else {
|
||||
headers = new NameValue[1];
|
||||
}
|
||||
|
||||
log.debug("creating login for {} with username {} password len {}", theTarget.getName(),
|
||||
theTarget.getUsername(), theTarget.getPassword().length());
|
||||
headers[index] = new NameValue();
|
||||
headers[index].setName("Authorization");
|
||||
// log.debug("Encoded login info {}", encodedLogin);
|
||||
headers[index].setValue("Basic " + encodedLogin);
|
||||
} else {
|
||||
headers = theHeaders;
|
||||
}
|
||||
|
||||
return headers;
|
||||
|
||||
}
|
||||
|
||||
public void setCallType(String callType) {
|
||||
this.callType = callType;
|
||||
}
|
||||
|
||||
public void closeHandler() {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,11 +16,14 @@ import com.bwssystems.HABridge.hue.ColorDecode;
|
||||
import com.bwssystems.HABridge.hue.DeviceDataDecode;
|
||||
import com.bwssystems.HABridge.hue.MultiCommandUtil;
|
||||
import com.bwssystems.HABridge.hue.TimeDecode;
|
||||
import com.bwssystems.HABridge.plugins.fibaro.FibaroTestData;
|
||||
import com.bwssystems.HABridge.plugins.vera.VeraTestData;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
public class HTTPHome implements Home {
|
||||
private static final Logger log = LoggerFactory.getLogger(HTTPHome.class);
|
||||
private static HTTPHandler anHttpHandler = null;
|
||||
private Boolean isDevMode;
|
||||
private boolean closed;
|
||||
|
||||
public HTTPHome(BridgeSettings bridgeSettings) {
|
||||
@@ -41,7 +44,7 @@ public class HTTPHome implements Home {
|
||||
Integer targetBri,Integer targetBriInc, ColorData colorData, DeviceDescriptor device, String body) {
|
||||
String responseString = null;
|
||||
|
||||
String theUrl = anItem.getItem().getAsString();
|
||||
String theUrl = anItem.getItem().getAsString().replaceAll("^\"|\"$", "");
|
||||
if(theUrl != null && !theUrl.isEmpty () && (theUrl.startsWith("http://") || theUrl.startsWith("https://"))) {
|
||||
//Backwards Compatibility Items
|
||||
if(anItem.getHttpVerb() == null || anItem.getHttpVerb().isEmpty())
|
||||
@@ -78,18 +81,21 @@ public class HTTPHome implements Home {
|
||||
aBody = TimeDecode.replaceTimeValue(aBody);
|
||||
}
|
||||
// make call
|
||||
if (anHttpHandler.doHttpRequest(anUrl, anItem.getHttpVerb(), anItem.getContentType(), aBody,
|
||||
new Gson().fromJson(anItem.getHttpHeaders(), NameValue[].class)) == null) {
|
||||
String httpReply = anHttpHandler.doHttpRequest(anUrl, anItem.getHttpVerb(), anItem.getContentType(), aBody, new Gson().fromJson(anItem.getHttpHeaders(), NameValue[].class));
|
||||
if (httpReply == null) {
|
||||
log.warn("Error on calling url to change device state: " + anUrl);
|
||||
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
|
||||
"Error on calling url to change device state", "/lights/"
|
||||
+ lightId + "state", null, null).getTheErrors(), HueError[].class);
|
||||
+ lightId + "/state", null, null).getTheErrors(), HueError[].class);
|
||||
}
|
||||
|
||||
if(isDevMode)
|
||||
log.info("Dev Mode response dump <<<" + httpReply +">>>");
|
||||
} else {
|
||||
log.warn("HTTP Call to be presented as http(s)://<ip_address>(:<port>)/payload, format of request unknown: " + theUrl);
|
||||
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
|
||||
"Error on calling url to change device state", "/lights/"
|
||||
+ lightId + "state", null, null).getTheErrors(), HueError[].class);
|
||||
+ lightId + "/state", null, null).getTheErrors(), HueError[].class);
|
||||
}
|
||||
|
||||
return responseString;
|
||||
@@ -97,9 +103,21 @@ public class HTTPHome implements Home {
|
||||
|
||||
@Override
|
||||
public Home createHome(BridgeSettings bridgeSettings) {
|
||||
isDevMode = Boolean.parseBoolean(System.getProperty("dev.mode", "false"));
|
||||
log.info("HTTP Home created." + (isDevMode ? " DevMode is set." : ""));
|
||||
if(isDevMode) {
|
||||
anHttpHandler = new HttpTestHandler();
|
||||
((HttpTestHandler)anHttpHandler).setTheData("id=sdata", VeraTestData.SDataTestData);
|
||||
((HttpTestHandler)anHttpHandler).setTheData("action=SetLoadLevelTarget", VeraTestData.SetLoadLevelTargetData);
|
||||
((HttpTestHandler)anHttpHandler).setTheData("action=SetTarget", VeraTestData.SetTargetData);
|
||||
((HttpTestHandler)anHttpHandler).setTheData("action=RunScene", VeraTestData.RunSceneData);
|
||||
((HttpTestHandler)anHttpHandler).setTheData("/api/callAction", FibaroTestData.CallActionTestData);
|
||||
((HttpTestHandler)anHttpHandler).setTheData("/api/sceneControl", FibaroTestData.SceneControlTestData);
|
||||
((HttpTestHandler)anHttpHandler).setTheData(null, "generic treply - no match");
|
||||
|
||||
}
|
||||
if(anHttpHandler == null)
|
||||
anHttpHandler = new HTTPHandler();
|
||||
log.info("Http Home created.");
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -121,5 +139,9 @@ public class HTTPHome implements Home {
|
||||
anHttpHandler = null;
|
||||
closed = true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void refresh() {
|
||||
// noop
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,22 @@ import java.io.IOException;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||
import org.apache.http.config.Registry;
|
||||
import org.apache.http.config.RegistryBuilder;
|
||||
import org.apache.http.conn.socket.ConnectionSocketFactory;
|
||||
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
|
||||
import org.apache.http.conn.ssl.NoopHostnameVerifier;
|
||||
import org.apache.http.ssl.SSLContexts;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
||||
import org.apache.http.conn.ssl.TrustStrategy;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -31,9 +43,7 @@ public final class HttpClientPool {
|
||||
// Increase default max connection per route to 20
|
||||
cm.setDefaultMaxPerRoute(20);
|
||||
// Build the client.
|
||||
threadSafeClient = HttpClients.custom()
|
||||
.setConnectionManager(cm)
|
||||
.build();
|
||||
threadSafeClient = HttpClients.custom().setConnectionManager(cm).build();
|
||||
// Start up an eviction thread.
|
||||
monitor = new IdleConnectionMonitorThread(cm);
|
||||
// Don't stop quitting.
|
||||
@@ -47,11 +57,67 @@ public final class HttpClientPool {
|
||||
|
||||
}
|
||||
|
||||
// Single-element enum to implement Singleton.
|
||||
private static enum SingletonSSL {
|
||||
// Just one of me so constructor will be called once.
|
||||
SSLClient;
|
||||
// The thread-safe client.
|
||||
private CloseableHttpClient threadSafeClient;
|
||||
// The pool monitor.
|
||||
private IdleConnectionMonitorThread monitor = null;
|
||||
private TrustStrategy acceptingTrustStrategy = null;
|
||||
private SSLContext sslContext = null;
|
||||
private SSLConnectionSocketFactory sslsf = null;
|
||||
private Registry<ConnectionSocketFactory> socketFactoryRegistry = null;
|
||||
private NoopHostnameVerifier hostnameVerifier = null;
|
||||
|
||||
// The constructor creates it - thus late
|
||||
private SingletonSSL() {
|
||||
try {
|
||||
acceptingTrustStrategy = (cert, authType) -> true;
|
||||
hostnameVerifier = new NoopHostnameVerifier();
|
||||
sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
|
||||
sslsf = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
|
||||
HttpClientPool.log.info("Instantiated SSL components.");
|
||||
final Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
|
||||
.register("http", new PlainConnectionSocketFactory())
|
||||
.register("https", sslsf)
|
||||
.build();
|
||||
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
|
||||
// Increase max total connection to 200
|
||||
cm.setMaxTotal(200);
|
||||
// Increase default max connection per route to 20
|
||||
cm.setDefaultMaxPerRoute(20);
|
||||
|
||||
// Build the client.
|
||||
threadSafeClient = HttpClients.custom().setSSLSocketFactory(sslsf).setConnectionManager(cm).build();
|
||||
// Start up an eviction thread.
|
||||
monitor = new IdleConnectionMonitorThread(cm);
|
||||
// Don't stop quitting.
|
||||
monitor.setDaemon(true);
|
||||
monitor.start();
|
||||
} catch (Exception e) {
|
||||
HttpClientPool.log.warn("SingletonSSL failed on SSL init");
|
||||
threadSafeClient = null;
|
||||
}
|
||||
}
|
||||
|
||||
public CloseableHttpClient get() {
|
||||
return threadSafeClient;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static CloseableHttpClient getClient() {
|
||||
// The thread safe client is held by the singleton.
|
||||
return Singleton.Client.get();
|
||||
}
|
||||
|
||||
public static CloseableHttpClient getSSLClient() {
|
||||
// The thread safe client is held by the singleton.
|
||||
return SingletonSSL.SSLClient.get();
|
||||
}
|
||||
|
||||
// Watches for stale connections and evicts them.
|
||||
private static class IdleConnectionMonitorThread extends Thread {
|
||||
// The manager to watch.
|
||||
@@ -123,6 +189,7 @@ public final class HttpClientPool {
|
||||
public static void shutdown() throws InterruptedException, IOException {
|
||||
// Shutdown the monitor.
|
||||
Singleton.Client.monitor.shutdown();
|
||||
SingletonSSL.SSLClient.monitor.shutdown();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.bwssystems.HABridge.plugins.http;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.bwssystems.HABridge.api.NameValue;
|
||||
import com.bwssystems.HABridge.plugins.http.HTTPHandler;
|
||||
|
||||
public class HttpTestHandler extends HTTPHandler {
|
||||
private static final Logger log = LoggerFactory.getLogger(HttpTestHandler.class);
|
||||
private List<NameValue> theData;
|
||||
|
||||
public void setTheData(String compareValue, String testData) {
|
||||
if( this.theData == null )
|
||||
this.theData = new ArrayList<NameValue>();
|
||||
NameValue aValueSet = new NameValue();
|
||||
aValueSet.setName(compareValue);
|
||||
aValueSet.setValue(testData);
|
||||
this.theData.add(aValueSet);
|
||||
}
|
||||
|
||||
public void updateTheData(String compareValue, String testData) {
|
||||
if( this.theData == null ) {
|
||||
this.theData = new ArrayList<NameValue>();
|
||||
NameValue aValueSet = new NameValue();
|
||||
aValueSet.setName(compareValue);
|
||||
aValueSet.setValue(testData);
|
||||
this.theData.add(aValueSet);
|
||||
}
|
||||
else {
|
||||
for(NameValue aTest:this.theData) {
|
||||
if(aTest.getName().equals(compareValue))
|
||||
aTest.setValue(testData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String doHttpRequest(String url, String httpVerb, String contentType, String body, NameValue[] headers) {
|
||||
log.info("doHttpRequest with url <<<" + url + ">>>, verb: " + httpVerb + ", contentType: " + contentType + ", body <<<" + body + ">>>" );
|
||||
if(headers != null && headers.length > 0)
|
||||
for(int i = 0; i < headers.length; i++)
|
||||
log.info("header index " + i + " name: <<<" + headers[i].getName() + ">>>, value: <<<" + headers[i].getValue() + ">>>");
|
||||
String responseData = null;
|
||||
for(NameValue aTest:theData) {
|
||||
if(aTest.getName() == null)
|
||||
responseData = aTest.getValue();
|
||||
else {
|
||||
if(url.contains(aTest.getName()))
|
||||
responseData = aTest.getValue();
|
||||
else if(aTest.getName() == null || aTest.getName().isEmpty())
|
||||
responseData = aTest.getValue();
|
||||
}
|
||||
|
||||
if(responseData != null)
|
||||
break;
|
||||
}
|
||||
|
||||
if(responseData == null)
|
||||
responseData = "No data was set for HttpTestHandler for your request url.";
|
||||
return responseData;
|
||||
}
|
||||
}
|
||||
@@ -99,7 +99,7 @@ public class HueHome implements Home {
|
||||
if(anItem.getItem().isJsonObject())
|
||||
deviceId = aGsonHandler.fromJson(anItem.getItem(), HueDeviceIdentifier.class);
|
||||
else
|
||||
deviceId = aGsonHandler.fromJson(anItem.getItem().getAsString(), HueDeviceIdentifier.class);
|
||||
deviceId = aGsonHandler.fromJson(anItem.getItem().getAsString().replaceAll("^\"|\"$", ""), HueDeviceIdentifier.class);
|
||||
if(deviceId.getHueName() == null || deviceId.getHueName().isEmpty())
|
||||
deviceId.setHueName(device.getTargetDevice());
|
||||
|
||||
@@ -153,4 +153,9 @@ public class HueHome implements Home {
|
||||
hues = null;
|
||||
closed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh() {
|
||||
// noop
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,10 +159,10 @@ public class HueInfo {
|
||||
log.warn("Error on calling Hue passthru to change device state: " + deviceId.getHueName());
|
||||
responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
|
||||
+ "\",\"description\": \"Error on calling HUE to change device state\", \"parameter\": \"/lights/"
|
||||
+ lightId + "state\"}}]";
|
||||
+ lightId + "/state\"}}]";
|
||||
} else if (responseString.contains("[{\"error\":")) {
|
||||
if(responseString.contains("unauthorized user")) {
|
||||
}
|
||||
// if(responseString.contains("unauthorized user")) {
|
||||
// }
|
||||
log.warn("Error occurred when calling Hue Passthru: " + responseString);
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -5,6 +5,7 @@ import java.net.Inet4Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InterfaceAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
@@ -20,6 +21,7 @@ import com.bwssystems.HABridge.api.CallItem;
|
||||
import com.bwssystems.HABridge.dao.DeviceDescriptor;
|
||||
import com.bwssystems.HABridge.hue.BrightnessDecode;
|
||||
import com.bwssystems.HABridge.hue.ColorData;
|
||||
import com.bwssystems.HABridge.hue.ColorDecode;
|
||||
import com.bwssystems.HABridge.hue.MultiCommandUtil;
|
||||
import com.github.besherman.lifx.LFXClient;
|
||||
import com.github.besherman.lifx.LFXGroup;
|
||||
@@ -38,6 +40,7 @@ public class LifxHome implements Home {
|
||||
private LFXClient client;
|
||||
private Boolean validLifx;
|
||||
private Gson aGsonHandler;
|
||||
private InetAddress configuredAddress;
|
||||
private boolean closed;
|
||||
|
||||
public LifxHome(BridgeSettings bridgeSettings) {
|
||||
@@ -54,47 +57,17 @@ public class LifxHome implements Home {
|
||||
validLifx = bridgeSettings.getBridgeSettingsDescriptor().isValidLifx();
|
||||
log.info("LifxDevice Home created." + (validLifx ? "" : " No LifxDevices configured."));
|
||||
if(validLifx) {
|
||||
try {
|
||||
log.info("Open Lifx client....");
|
||||
InetAddress configuredAddress = InetAddress.getByName(bridgeSettings.getBridgeSettingsDescriptor().getUpnpConfigAddress());
|
||||
NetworkInterface networkInterface = NetworkInterface.getByInetAddress(configuredAddress);
|
||||
InetAddress bcastInetAddr = null;
|
||||
if (networkInterface != null) {
|
||||
for (InterfaceAddress ifaceAddr : networkInterface.getInterfaceAddresses()) {
|
||||
InetAddress addr = ifaceAddr.getAddress();
|
||||
if (addr instanceof Inet4Address) {
|
||||
bcastInetAddr = ifaceAddr.getBroadcast();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(bcastInetAddr != null) {
|
||||
lifxMap = new HashMap<String, LifxDevice>();
|
||||
log.info("Opening LFX Client with broadcast address: " + bcastInetAddr.getHostAddress());
|
||||
client = new LFXClient(bcastInetAddr.getHostAddress());
|
||||
client.getLights().addLightCollectionListener(new MyLightListener(lifxMap));
|
||||
client.getGroups().addGroupCollectionListener(new MyGroupListener(lifxMap));
|
||||
client.open(false);
|
||||
aGsonHandler =
|
||||
new GsonBuilder()
|
||||
.create();
|
||||
} else {
|
||||
log.warn("Could not open LIFX, no bcast addr available, check your upnp config address.");
|
||||
client = null;
|
||||
validLifx = false;
|
||||
return this;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.warn("Could not open LIFX, with IO Exception", e);
|
||||
client = null;
|
||||
validLifx = false;
|
||||
return this;
|
||||
} catch (InterruptedException e) {
|
||||
log.warn("Could not open LIFX, with Interruprted Exception", e);
|
||||
client = null;
|
||||
aGsonHandler =
|
||||
new GsonBuilder()
|
||||
.create();
|
||||
try {
|
||||
configuredAddress = InetAddress.getByName(bridgeSettings.getBridgeSettingsDescriptor().getUpnpConfigAddress());
|
||||
} catch (UnknownHostException e) {
|
||||
log.warn("Could not get Inet Address for Lifx broadcast.");
|
||||
validLifx = false;
|
||||
return this;
|
||||
}
|
||||
broadcastDiscover();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@@ -116,7 +89,7 @@ public class LifxHome implements Home {
|
||||
@Override
|
||||
public Object getItems(String type) {
|
||||
log.debug("consolidating devices for lifx");
|
||||
if(!validLifx)
|
||||
if(!validLifx || lifxMap == null)
|
||||
return null;
|
||||
LifxEntry theResponse = null;
|
||||
Iterator<String> keys = lifxMap.keySet().iterator();
|
||||
@@ -171,20 +144,20 @@ public class LifxHome implements Home {
|
||||
log.warn("Should not get here, no LifxDevice clients configured");
|
||||
theReturn = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
|
||||
+ "\",\"description\": \"Should not get here, no LifxDevices configured\", \"parameter\": \"/lights/"
|
||||
+ lightId + "state\"}}]";
|
||||
+ lightId + "/state\"}}]";
|
||||
|
||||
} else {
|
||||
LifxEntry lifxCommand = null;
|
||||
if(anItem.getItem().isJsonObject())
|
||||
lifxCommand = aGsonHandler.fromJson(anItem.getItem(), LifxEntry.class);
|
||||
else
|
||||
lifxCommand = aGsonHandler.fromJson(anItem.getItem().getAsString(), LifxEntry.class);
|
||||
lifxCommand = aGsonHandler.fromJson(anItem.getItem().getAsString().replaceAll("^\"|\"$", ""), LifxEntry.class);
|
||||
LifxDevice theDevice = getLifxDevice(lifxCommand.getName());
|
||||
if (theDevice == null) {
|
||||
log.warn("Should not get here, no LifxDevices available");
|
||||
theReturn = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
|
||||
+ "\",\"description\": \"Should not get here, no Lifx clients available\", \"parameter\": \"/lights/"
|
||||
+ lightId + "state\"}}]";
|
||||
+ lightId + "/state\"}}]";
|
||||
} else {
|
||||
log.debug("calling LifxDevice: " + lifxCommand.getName());
|
||||
if(theDevice.getType().equals(LifxDevice.LIGHT_TYPE)) {
|
||||
@@ -200,6 +173,10 @@ public class LifxHome implements Home {
|
||||
theValue = (float)0.99;
|
||||
theLight.setBrightness(theValue);
|
||||
}
|
||||
if(colorData != null) {
|
||||
int rgbVal = ColorDecode.getIntRGB(colorData, intensity);
|
||||
theLight.setColor(rgbVal);
|
||||
}
|
||||
} else if (theDevice.getType().equals(LifxDevice.GROUP_TYPE)) {
|
||||
LFXGroup theGroup = (LFXGroup)theDevice.getLifxObject();
|
||||
if(body.contains("true"))
|
||||
@@ -221,7 +198,8 @@ public class LifxHome implements Home {
|
||||
log.debug("Home is already closed....");
|
||||
return;
|
||||
}
|
||||
client.close();
|
||||
if(client != null)
|
||||
client.close();
|
||||
closed = true;
|
||||
}
|
||||
private static class MyLightListener implements LFXLightCollectionListener {
|
||||
@@ -266,4 +244,47 @@ public class LifxHome implements Home {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void broadcastDiscover() {
|
||||
try {
|
||||
log.info("Open Lifx client....");
|
||||
NetworkInterface networkInterface = NetworkInterface.getByInetAddress(configuredAddress);
|
||||
InetAddress bcastInetAddr = null;
|
||||
if (networkInterface != null) {
|
||||
for (InterfaceAddress ifaceAddr : networkInterface.getInterfaceAddresses()) {
|
||||
InetAddress addr = ifaceAddr.getAddress();
|
||||
if (addr instanceof Inet4Address) {
|
||||
bcastInetAddr = ifaceAddr.getBroadcast();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(bcastInetAddr != null) {
|
||||
lifxMap = new HashMap<String, LifxDevice>();
|
||||
log.info("Opening LFX Client with broadcast address: " + bcastInetAddr.getHostAddress());
|
||||
client = new LFXClient(bcastInetAddr.getHostAddress());
|
||||
client.getLights().addLightCollectionListener(new MyLightListener(lifxMap));
|
||||
client.getGroups().addGroupCollectionListener(new MyGroupListener(lifxMap));
|
||||
client.open(false);
|
||||
} else {
|
||||
log.warn("Could not open LIFX, no bcast addr available, check your upnp config address.");
|
||||
client = null;
|
||||
return;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.warn("Could not open LIFX, with IO Exception", e);
|
||||
client = null;
|
||||
return;
|
||||
} catch (InterruptedException e) {
|
||||
log.warn("Could not open LIFX, with Interruprted Exception", e);
|
||||
client = null;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh() {
|
||||
if(client == null)
|
||||
broadcastDiscover();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
package com.bwssystems.HABridge.plugins.moziot;
|
||||
|
||||
|
||||
public class Actions {
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
package com.bwssystems.HABridge.plugins.moziot;
|
||||
|
||||
|
||||
public class Events {
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
|
||||
package com.bwssystems.HABridge.plugins.moziot;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class JWT {
|
||||
|
||||
@SerializedName("jwt")
|
||||
@Expose
|
||||
private String jwt;
|
||||
|
||||
public String getJwt() {
|
||||
return jwt;
|
||||
}
|
||||
|
||||
public void setJwt(String jwt) {
|
||||
this.jwt = jwt;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
|
||||
package com.bwssystems.HABridge.plugins.moziot;
|
||||
|
||||
import java.util.List;
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class Level {
|
||||
|
||||
@SerializedName("title")
|
||||
@Expose
|
||||
private String title;
|
||||
@SerializedName("type")
|
||||
@Expose
|
||||
private String type;
|
||||
@SerializedName("@type")
|
||||
@Expose
|
||||
private String attype;
|
||||
@SerializedName("unit")
|
||||
@Expose
|
||||
private String unit;
|
||||
@SerializedName("minimum")
|
||||
@Expose
|
||||
private Integer minimum;
|
||||
@SerializedName("maximum")
|
||||
@Expose
|
||||
private Integer maximum;
|
||||
@SerializedName("links")
|
||||
@Expose
|
||||
private List<Link> links = null;
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getAttype() {
|
||||
return attype;
|
||||
}
|
||||
|
||||
public void setAttype(String attype) {
|
||||
this.attype = attype;
|
||||
}
|
||||
|
||||
public String getUnit() {
|
||||
return unit;
|
||||
}
|
||||
|
||||
public void setUnit(String unit) {
|
||||
this.unit = unit;
|
||||
}
|
||||
|
||||
public Integer getMinimum() {
|
||||
return minimum;
|
||||
}
|
||||
|
||||
public void setMinimum(Integer minimum) {
|
||||
this.minimum = minimum;
|
||||
}
|
||||
|
||||
public Integer getMaximum() {
|
||||
return maximum;
|
||||
}
|
||||
|
||||
public void setMaximum(Integer maximum) {
|
||||
this.maximum = maximum;
|
||||
}
|
||||
|
||||
public List<Link> getLinks() {
|
||||
return links;
|
||||
}
|
||||
|
||||
public void setLinks(List<Link> links) {
|
||||
this.links = links;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
|
||||
package com.bwssystems.HABridge.plugins.moziot;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class Link {
|
||||
|
||||
@SerializedName("rel")
|
||||
@Expose
|
||||
private String rel;
|
||||
@SerializedName("href")
|
||||
@Expose
|
||||
private String href;
|
||||
@SerializedName("mediaType")
|
||||
@Expose
|
||||
private String mediaType;
|
||||
|
||||
public String getRel() {
|
||||
return rel;
|
||||
}
|
||||
|
||||
public void setRel(String rel) {
|
||||
this.rel = rel;
|
||||
}
|
||||
|
||||
public String getHref() {
|
||||
return href;
|
||||
}
|
||||
|
||||
public void setHref(String href) {
|
||||
this.href = href;
|
||||
}
|
||||
|
||||
public String getMediaType() {
|
||||
return mediaType;
|
||||
}
|
||||
|
||||
public void setMediaType(String mediaType) {
|
||||
this.mediaType = mediaType;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.bwssystems.HABridge.plugins.moziot;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class MozIotCommand {
|
||||
@SerializedName("url")
|
||||
@Expose
|
||||
private String url;
|
||||
@SerializedName("command")
|
||||
@Expose
|
||||
private MozIotCommandDetail command;
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
public MozIotCommandDetail getCommand() {
|
||||
return command;
|
||||
}
|
||||
public void setCommand(MozIotCommandDetail command) {
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.bwssystems.HABridge.plugins.moziot;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class MozIotCommandDetail {
|
||||
@SerializedName("on")
|
||||
@Expose
|
||||
private boolean on;
|
||||
@SerializedName("level")
|
||||
@Expose
|
||||
private String level;
|
||||
@SerializedName("color")
|
||||
@Expose
|
||||
private String color;
|
||||
|
||||
public boolean isOn() {
|
||||
return on;
|
||||
}
|
||||
|
||||
public void setOn(boolean on) {
|
||||
this.on = on;
|
||||
}
|
||||
|
||||
public String getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public void setLevel(String level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
public String getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public void setColor(String color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public String getBody() {
|
||||
String theBody = "";
|
||||
|
||||
if(level != null && level != "") {
|
||||
theBody = "{\"level\":" + level + "}";
|
||||
}
|
||||
else if(color != null && color != "") {
|
||||
theBody = "{\"color\":\"" + color + "\"}";
|
||||
} else {
|
||||
theBody = "{\"on\":" + on + "}";
|
||||
}
|
||||
return theBody;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.bwssystems.HABridge.plugins.moziot;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class MozIotDevice {
|
||||
@SerializedName("gatewayName")
|
||||
@Expose
|
||||
private String gatewayName;
|
||||
@SerializedName("deviceDetail")
|
||||
@Expose
|
||||
private MozillaThing deviceDetail;
|
||||
|
||||
public String getGatewayName() {
|
||||
return gatewayName;
|
||||
}
|
||||
|
||||
public void setGatewayName(String gatewayName) {
|
||||
this.gatewayName = gatewayName;
|
||||
}
|
||||
|
||||
public MozillaThing getDeviceDetail() {
|
||||
return deviceDetail;
|
||||
}
|
||||
|
||||
public void setDeviceDetail(MozillaThing deviceDetail) {
|
||||
this.deviceDetail = deviceDetail;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
package com.bwssystems.HABridge.plugins.moziot;
|
||||
|
||||
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.BridgeSettings;
|
||||
import com.bwssystems.HABridge.Home;
|
||||
import com.bwssystems.HABridge.NamedIP;
|
||||
import com.bwssystems.HABridge.api.CallItem;
|
||||
import com.bwssystems.HABridge.api.hue.HueError;
|
||||
import com.bwssystems.HABridge.api.hue.HueErrorResponse;
|
||||
import com.bwssystems.HABridge.dao.DeviceDescriptor;
|
||||
import com.bwssystems.HABridge.hue.BrightnessDecode;
|
||||
import com.bwssystems.HABridge.hue.ColorData;
|
||||
import com.bwssystems.HABridge.hue.ColorDecode;
|
||||
import com.bwssystems.HABridge.hue.DeviceDataDecode;
|
||||
import com.bwssystems.HABridge.hue.MultiCommandUtil;
|
||||
import com.bwssystems.HABridge.hue.TimeDecode;
|
||||
import com.bwssystems.HABridge.plugins.http.HTTPHandler;
|
||||
import com.bwssystems.HABridge.plugins.http.HTTPHome;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
public class MozIotHome implements Home {
|
||||
private static final Logger log = LoggerFactory.getLogger(MozIotHome.class);
|
||||
private Map<String, MozIotInstance> moziotMap;
|
||||
private Boolean validMoziot;
|
||||
private HTTPHandler httpClient;
|
||||
private boolean closed;
|
||||
|
||||
public MozIotHome(BridgeSettings bridgeSettings) {
|
||||
super();
|
||||
closed = true;
|
||||
createHome(bridgeSettings);
|
||||
closed = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String deviceHandler(CallItem anItem, MultiCommandUtil aMultiUtil, String lightId, int intensity,
|
||||
Integer targetBri, Integer targetBriInc, ColorData colorData, DeviceDescriptor device, String body) {
|
||||
|
||||
String theUrl = anItem.getItem().getAsString().replaceAll("^\"|\"$", "");
|
||||
String responseString = null;
|
||||
|
||||
if (theUrl != null && !theUrl.isEmpty()) {
|
||||
String anUrl = BrightnessDecode.calculateReplaceIntensityValue(theUrl, intensity, targetBri, targetBriInc,
|
||||
false);
|
||||
if (colorData != null) {
|
||||
anUrl = ColorDecode.replaceColorData(anUrl, colorData,
|
||||
BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc), true);
|
||||
}
|
||||
anUrl = DeviceDataDecode.replaceDeviceData(anUrl, device);
|
||||
anUrl = TimeDecode.replaceTimeValue(anUrl);
|
||||
|
||||
anUrl = BrightnessDecode.calculateReplaceIntensityValue(anUrl, intensity, targetBri, targetBriInc, false);
|
||||
if (colorData != null) {
|
||||
anUrl = ColorDecode.replaceColorData(anUrl, colorData,
|
||||
BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc), false);
|
||||
}
|
||||
anUrl = DeviceDataDecode.replaceDeviceData(anUrl, device);
|
||||
anUrl = TimeDecode.replaceTimeValue(anUrl);
|
||||
|
||||
MozIotCommand theCommand = null;
|
||||
try {
|
||||
theUrl = theUrl.replaceAll("^\"|\"$", "");
|
||||
theCommand = new Gson().fromJson(anUrl, MozIotCommand.class);
|
||||
} catch (Exception e) {
|
||||
log.warn("Cannot parse command to Mozilla IOT <<<" + theUrl + ">>>", e);
|
||||
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
|
||||
"Error on calling url to change device state", "/lights/" + lightId + "/state", null, null)
|
||||
.getTheErrors(), HueError[].class);
|
||||
return responseString;
|
||||
}
|
||||
|
||||
String intermediate = theCommand.getUrl().substring(theCommand.getUrl().indexOf("/things/") + 8);
|
||||
String devicePortion = intermediate.substring(0, intermediate.indexOf('/'));
|
||||
String theUrlCommand = intermediate.substring(intermediate.indexOf('/') + 1);
|
||||
MozIotInstance theHandler = moziotMap.get(device.getTargetDevice());
|
||||
if (theHandler != null) {
|
||||
try {
|
||||
boolean success = theHandler.callCommand(devicePortion, theUrlCommand, theCommand.getCommand(), httpClient);
|
||||
if (!success) {
|
||||
log.warn("Comand had error to Mozilla IOT");
|
||||
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
|
||||
"Error on calling url to change device state", "/lights/" + lightId + "/state", null,
|
||||
null).getTheErrors(), HueError[].class);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("Cannot send comand to Mozilla IOT", e);
|
||||
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
|
||||
"Error on calling url to change device state", "/lights/" + lightId + "/state", null, null)
|
||||
.getTheErrors(), HueError[].class);
|
||||
}
|
||||
} else {
|
||||
log.warn("Mozilla IOT Call could not complete, no address found: " + theUrl);
|
||||
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
|
||||
"Error on calling url to change device state", "/lights/" + lightId + "/state", null, null)
|
||||
.getTheErrors(), HueError[].class);
|
||||
}
|
||||
} else {
|
||||
log.warn(
|
||||
"Mozilla IOT Call to be presented as http(s)://<ip_address>(:<port>)/payload, format of request unknown: "
|
||||
+ theUrl);
|
||||
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
|
||||
"Error on calling url to change device state", "/lights/" + lightId + "/state", null, null)
|
||||
.getTheErrors(), HueError[].class);
|
||||
}
|
||||
return responseString;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getItems(String type) {
|
||||
|
||||
if (!validMoziot)
|
||||
return null;
|
||||
log.debug("consolidating devices for Mozilla IOT");
|
||||
List<MozillaThing> theResponse = null;
|
||||
Iterator<String> keys = moziotMap.keySet().iterator();
|
||||
List<MozIotDevice> deviceList = new ArrayList<MozIotDevice>();
|
||||
while (keys.hasNext()) {
|
||||
String key = keys.next();
|
||||
theResponse = moziotMap.get(key).getDevices(httpClient);
|
||||
if (theResponse != null)
|
||||
addMozIotDevices(deviceList, theResponse, key);
|
||||
else {
|
||||
log.warn("Cannot get devices for Mozilla IOT with name: " + key + ", skipping this Mozilla IOT.");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return deviceList;
|
||||
}
|
||||
|
||||
private Boolean addMozIotDevices(List<MozIotDevice> theDeviceList, List<MozillaThing> theSourceList,
|
||||
String theKey) {
|
||||
Iterator<MozillaThing> things = theSourceList.iterator();
|
||||
while (things.hasNext()) {
|
||||
MozillaThing theThing = things.next();
|
||||
MozIotDevice theDevice = new MozIotDevice();
|
||||
theDevice.setDeviceDetail(theThing);
|
||||
theDevice.setGatewayName(theKey);
|
||||
theDeviceList.add(theDevice);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Home createHome(BridgeSettings bridgeSettings) {
|
||||
moziotMap = null;
|
||||
validMoziot = bridgeSettings.getBridgeSettingsDescriptor().isValidMozIot();
|
||||
log.info("Mozilla IOT Home created." + (validMoziot ? "" : " No Mozilla IOTs configured."));
|
||||
if (validMoziot) {
|
||||
moziotMap = new HashMap<String, MozIotInstance>();
|
||||
httpClient = HTTPHome.getHandler();
|
||||
Iterator<NamedIP> theList = bridgeSettings.getBridgeSettingsDescriptor().getMoziotaddress().getDevices()
|
||||
.iterator();
|
||||
while (theList.hasNext() && validMoziot) {
|
||||
NamedIP aMoziot = theList.next();
|
||||
try {
|
||||
moziotMap.put(aMoziot.getName(), new MozIotInstance(aMoziot, httpClient));
|
||||
} catch (Exception e) {
|
||||
log.error("Cannot get Mozilla IOT (" + aMoziot.getName() + ") setup, Exiting with message: "
|
||||
+ e.getMessage(), e);
|
||||
validMoziot = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeHome() {
|
||||
log.debug("Closing Home.");
|
||||
if (!closed && validMoziot) {
|
||||
log.debug("Home is already closed....");
|
||||
return;
|
||||
}
|
||||
|
||||
if (httpClient != null)
|
||||
httpClient.closeHandler();
|
||||
|
||||
moziotMap = null;
|
||||
closed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh() {
|
||||
// noop
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
package com.bwssystems.HABridge.plugins.moziot;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.bwssystems.HABridge.NamedIP;
|
||||
import com.bwssystems.HABridge.api.NameValue;
|
||||
import com.bwssystems.HABridge.plugins.http.HTTPHandler;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpPut;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class MozIotInstance {
|
||||
private static final Logger log = LoggerFactory.getLogger(MozIotInstance.class);
|
||||
private JWT moziotToken;
|
||||
private NamedIP mozIotIP;
|
||||
private NameValue[] headers;
|
||||
|
||||
public MozIotInstance(NamedIP theNamedIp, HTTPHandler httpClient) {
|
||||
mozIotIP = theNamedIp;
|
||||
headers = null;
|
||||
gatewayLogin(httpClient);
|
||||
}
|
||||
|
||||
public Boolean callCommand(String deviceId, String aCommand, MozIotCommandDetail commandData, HTTPHandler httpClient) {
|
||||
log.debug("calling Mozilla IOT: {}:{}{}{}", mozIotIP.getIp(), mozIotIP.getPort(), aCommand, commandData.getBody());
|
||||
String aUrl = null;
|
||||
|
||||
if (mozIotIP.getSecure() != null && mozIotIP.getSecure())
|
||||
aUrl = "https://";
|
||||
else
|
||||
aUrl = "http://";
|
||||
headers = getAuthHeader();
|
||||
|
||||
aUrl = aUrl + mozIotIP.getIp() + ":" + mozIotIP.getPort() + "/things/" + deviceId + "/" + aCommand;
|
||||
String theData = httpClient.doHttpRequest(aUrl, HttpPut.METHOD_NAME, "application/json", commandData.getBody(), headers);
|
||||
log.debug("call Command return is: <<<{}>>>", theData);
|
||||
if (theData.contains("error") || theData.contains("ERROR") || theData.contains("Error"))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public List<MozillaThing> getDevices(HTTPHandler httpClient) {
|
||||
log.debug("calling Mozilla IOT: " + mozIotIP.getIp() + ":" + mozIotIP.getPort());
|
||||
List<MozillaThing> deviceList = null;
|
||||
MozillaThing[] theThings;
|
||||
String theUrl = null;
|
||||
String theData;
|
||||
|
||||
if (mozIotIP.getSecure() != null && mozIotIP.getSecure())
|
||||
theUrl = "https://";
|
||||
else
|
||||
theUrl = "http://";
|
||||
headers = getAuthHeader();
|
||||
|
||||
theUrl = theUrl + mozIotIP.getIp() + ":" + mozIotIP.getPort() + "/things";
|
||||
theData = httpClient.doHttpRequest(theUrl, HttpGet.METHOD_NAME, "application/json", null, headers);
|
||||
if (theData != null) {
|
||||
log.debug("GET Mozilla IOT Devices - data: " + theData);
|
||||
try {
|
||||
theThings = new Gson().fromJson(theData, MozillaThing[].class);
|
||||
if (theThings != null && theThings.length > 0) {
|
||||
deviceList = new ArrayList<MozillaThing>();
|
||||
for (int i = 0; i < theThings.length; i++) {
|
||||
deviceList.add(theThings[i]);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("Cannot get an devices for Mozilla IOT {} Gson Parse Error.", mozIotIP.getName());
|
||||
}
|
||||
}
|
||||
return deviceList;
|
||||
}
|
||||
|
||||
private NameValue[] getAuthHeader() {
|
||||
if (headers == null) {
|
||||
headers = new NameValue[3];
|
||||
headers[0] = new NameValue();
|
||||
headers[0].setName("Authorization");
|
||||
headers[0].setValue("Bearer " + moziotToken.getJwt());
|
||||
headers[1] = new NameValue();
|
||||
headers[1].setName("Content-Type");
|
||||
headers[1].setValue("application/json");
|
||||
headers[2] = new NameValue();
|
||||
headers[2].setName("Accept");
|
||||
headers[2].setValue("application/json");
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
|
||||
private void gatewayLogin(HTTPHandler httpClient) {
|
||||
String aUrl = null;
|
||||
|
||||
if (mozIotIP.getSecure() != null && mozIotIP.getSecure())
|
||||
aUrl = "https://";
|
||||
else
|
||||
aUrl = "http://";
|
||||
|
||||
headers = new NameValue[2];
|
||||
headers[0] = new NameValue();
|
||||
headers[0].setName("Content-Type");
|
||||
headers[0].setValue("application/json");
|
||||
headers[1] = new NameValue();
|
||||
headers[1].setName("Accept");
|
||||
headers[1].setValue("application/json");
|
||||
aUrl = aUrl + mozIotIP.getIp() + ":" + mozIotIP.getPort() + "/login";
|
||||
log.debug("gateway login URL: {}", aUrl);
|
||||
String commandData = "{\"email\": \"" + mozIotIP.getUsername() + "\", \"password\":\"" + mozIotIP.getPassword()
|
||||
+ "\"}";
|
||||
log.debug("The login body: {}", commandData);
|
||||
String theData = httpClient.doHttpRequest(aUrl, HttpPost.METHOD_NAME, "application/json", commandData, headers);
|
||||
if (theData != null) {
|
||||
log.debug("GET Mozilla login - data: {}", theData);
|
||||
try {
|
||||
moziotToken = new Gson().fromJson(theData, JWT.class);
|
||||
} catch (Exception e) {
|
||||
log.warn("Cannot get login for Mozilla IOT {} Gson Parse Error.", mozIotIP.getName());
|
||||
}
|
||||
} else {
|
||||
log.warn("Could not login {} error: <<<{}>>>", mozIotIP.getName(), theData);
|
||||
}
|
||||
|
||||
headers = null;
|
||||
}
|
||||
|
||||
public NamedIP getMozIotIP() {
|
||||
return mozIotIP;
|
||||
}
|
||||
|
||||
public void setMozIotIP(NamedIP mozIotIP) {
|
||||
this.mozIotIP = mozIotIP;
|
||||
}
|
||||
|
||||
protected void closeClient() {
|
||||
}
|
||||
|
||||
public JWT getMoziotToken() {
|
||||
return moziotToken;
|
||||
}
|
||||
|
||||
public void setMoziotToken(JWT moziotToken) {
|
||||
this.moziotToken = moziotToken;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
|
||||
package com.bwssystems.HABridge.plugins.moziot;
|
||||
|
||||
import java.util.List;
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class MozillaThing {
|
||||
|
||||
@SerializedName("name")
|
||||
@Expose
|
||||
private String name;
|
||||
@SerializedName("type")
|
||||
@Expose
|
||||
private String type;
|
||||
@SerializedName("@context")
|
||||
@Expose
|
||||
private String atcontext;
|
||||
@SerializedName("@type")
|
||||
@Expose
|
||||
private List<String> attype = null;
|
||||
@SerializedName("description")
|
||||
@Expose
|
||||
private String description;
|
||||
@SerializedName("href")
|
||||
@Expose
|
||||
private String href;
|
||||
@SerializedName("properties")
|
||||
@Expose
|
||||
private Properties properties;
|
||||
@SerializedName("actions")
|
||||
@Expose
|
||||
private Actions actions;
|
||||
@SerializedName("events")
|
||||
@Expose
|
||||
private Events events;
|
||||
@SerializedName("links")
|
||||
@Expose
|
||||
private List<Link> links = null;
|
||||
@SerializedName("layoutIndex")
|
||||
@Expose
|
||||
private Integer layoutIndex;
|
||||
@SerializedName("selectedCapability")
|
||||
@Expose
|
||||
private String selectedCapability;
|
||||
@SerializedName("iconHref")
|
||||
@Expose
|
||||
private Object iconHref;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getAtcontext() {
|
||||
return atcontext;
|
||||
}
|
||||
|
||||
public void setAtcontext(String atcontext) {
|
||||
this.atcontext = atcontext;
|
||||
}
|
||||
|
||||
public List<String> getAttype() {
|
||||
return attype;
|
||||
}
|
||||
|
||||
public void setAttype(List<String> attype) {
|
||||
this.attype = attype;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getHref() {
|
||||
return href;
|
||||
}
|
||||
|
||||
public void setHref(String href) {
|
||||
this.href = href;
|
||||
}
|
||||
|
||||
public Properties getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
public void setProperties(Properties properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
public Actions getActions() {
|
||||
return actions;
|
||||
}
|
||||
|
||||
public void setActions(Actions actions) {
|
||||
this.actions = actions;
|
||||
}
|
||||
|
||||
public Events getEvents() {
|
||||
return events;
|
||||
}
|
||||
|
||||
public void setEvents(Events events) {
|
||||
this.events = events;
|
||||
}
|
||||
|
||||
public List<Link> getLinks() {
|
||||
return links;
|
||||
}
|
||||
|
||||
public void setLinks(List<Link> links) {
|
||||
this.links = links;
|
||||
}
|
||||
|
||||
public Integer getLayoutIndex() {
|
||||
return layoutIndex;
|
||||
}
|
||||
|
||||
public void setLayoutIndex(Integer layoutIndex) {
|
||||
this.layoutIndex = layoutIndex;
|
||||
}
|
||||
|
||||
public String getSelectedCapability() {
|
||||
return selectedCapability;
|
||||
}
|
||||
|
||||
public void setSelectedCapability(String selectedCapability) {
|
||||
this.selectedCapability = selectedCapability;
|
||||
}
|
||||
|
||||
public Object getIconHref() {
|
||||
return iconHref;
|
||||
}
|
||||
|
||||
public void setIconHref(Object iconHref) {
|
||||
this.iconHref = iconHref;
|
||||
}
|
||||
|
||||
}
|
||||
55
src/main/java/com/bwssystems/HABridge/plugins/moziot/On.java
Normal file
55
src/main/java/com/bwssystems/HABridge/plugins/moziot/On.java
Normal file
@@ -0,0 +1,55 @@
|
||||
|
||||
package com.bwssystems.HABridge.plugins.moziot;
|
||||
|
||||
import java.util.List;
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class On {
|
||||
|
||||
@SerializedName("title")
|
||||
@Expose
|
||||
private String title;
|
||||
@SerializedName("type")
|
||||
@Expose
|
||||
private String type;
|
||||
@SerializedName("attype")
|
||||
@Expose
|
||||
private String attype;
|
||||
@SerializedName("links")
|
||||
@Expose
|
||||
private List<Link> links = null;
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getAttype() {
|
||||
return attype;
|
||||
}
|
||||
|
||||
public void setAttype(String attype) {
|
||||
this.attype = attype;
|
||||
}
|
||||
|
||||
public List<Link> getLinks() {
|
||||
return links;
|
||||
}
|
||||
|
||||
public void setLinks(List<Link> links) {
|
||||
this.links = links;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
|
||||
package com.bwssystems.HABridge.plugins.moziot;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class Properties {
|
||||
|
||||
@SerializedName("on")
|
||||
@Expose
|
||||
private On on;
|
||||
@SerializedName("level")
|
||||
@Expose
|
||||
private Level level;
|
||||
|
||||
public On getOn() {
|
||||
return on;
|
||||
}
|
||||
|
||||
public void setOn(On on) {
|
||||
this.on = on;
|
||||
}
|
||||
|
||||
public Level getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public void setLevel(Level level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import com.bwssystems.HABridge.api.CallItem;
|
||||
import com.bwssystems.HABridge.dao.DeviceDescriptor;
|
||||
import com.bwssystems.HABridge.hue.BrightnessDecode;
|
||||
import com.bwssystems.HABridge.hue.ColorData;
|
||||
import com.bwssystems.HABridge.hue.ColorDecode;
|
||||
import com.bwssystems.HABridge.hue.DeviceDataDecode;
|
||||
import com.bwssystems.HABridge.hue.MultiCommandUtil;
|
||||
import com.bwssystems.HABridge.hue.TimeDecode;
|
||||
@@ -95,11 +96,14 @@ public class MQTTHome implements Home {
|
||||
mqttObject = aGsonHandler.toJson(anItem.getItem());
|
||||
}
|
||||
else
|
||||
mqttObject =anItem.getItem().getAsString();
|
||||
mqttObject = anItem.getItem().getAsString().replaceAll("^\"|\"$", "");
|
||||
mqttObject = BrightnessDecode.calculateReplaceIntensityValue(mqttObject,
|
||||
intensity, targetBri, targetBriInc, false);
|
||||
mqttObject = DeviceDataDecode.replaceDeviceData(mqttObject, device);
|
||||
mqttObject = TimeDecode.replaceTimeValue(mqttObject);
|
||||
if (colorData != null) {
|
||||
mqttObject = ColorDecode.replaceColorData(mqttObject, colorData, BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc), false);
|
||||
}
|
||||
if (mqttObject.substring(0, 1).equalsIgnoreCase("{"))
|
||||
mqttObject = "[" + mqttObject + "]";
|
||||
MQTTMessage[] mqttMessages = aGsonHandler.fromJson(mqttObject, MQTTMessage[].class);
|
||||
@@ -124,7 +128,7 @@ public class MQTTHome implements Home {
|
||||
log.warn("Should not get here, no mqtt brokers configured");
|
||||
responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
|
||||
+ "\",\"description\": \"Should not get here, no mqtt brokers configured\", \"parameter\": \"/lights/"
|
||||
+ lightId + "state\"}}]";
|
||||
+ lightId + "/state\"}}]";
|
||||
|
||||
}
|
||||
return responseString;
|
||||
@@ -146,4 +150,9 @@ public class MQTTHome implements Home {
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh() {
|
||||
// noop
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.bwssystems.HABridge.plugins.openhab;
|
||||
|
||||
public class OpenHABCommand {
|
||||
private String url;
|
||||
private String command;
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
public String getCommand() {
|
||||
return command;
|
||||
}
|
||||
public void setCommand(String command) {
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.bwssystems.HABridge.plugins.openhab;
|
||||
|
||||
public class OpenHABDevice {
|
||||
|
||||
private String address;
|
||||
private String name;
|
||||
private OpenHABItem item;
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
public OpenHABItem getItem() {
|
||||
return item;
|
||||
}
|
||||
public void setItem(OpenHABItem item) {
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,211 @@
|
||||
package com.bwssystems.HABridge.plugins.openhab;
|
||||
|
||||
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.BridgeSettings;
|
||||
import com.bwssystems.HABridge.Home;
|
||||
import com.bwssystems.HABridge.NamedIP;
|
||||
import com.bwssystems.HABridge.api.CallItem;
|
||||
import com.bwssystems.HABridge.api.hue.HueError;
|
||||
import com.bwssystems.HABridge.api.hue.HueErrorResponse;
|
||||
import com.bwssystems.HABridge.dao.DeviceDescriptor;
|
||||
import com.bwssystems.HABridge.hue.BrightnessDecode;
|
||||
import com.bwssystems.HABridge.hue.ColorData;
|
||||
import com.bwssystems.HABridge.hue.ColorDecode;
|
||||
import com.bwssystems.HABridge.hue.DeviceDataDecode;
|
||||
import com.bwssystems.HABridge.hue.MultiCommandUtil;
|
||||
import com.bwssystems.HABridge.hue.TimeDecode;
|
||||
import com.bwssystems.HABridge.plugins.http.HTTPHandler;
|
||||
import com.bwssystems.HABridge.plugins.http.HTTPHome;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
public class OpenHABHome implements Home {
|
||||
private static final Logger log = LoggerFactory.getLogger(OpenHABHome.class);
|
||||
private Map<String, OpenHABInstance> openhabMap;
|
||||
private Boolean validOpenhab;
|
||||
private HTTPHandler httpClient;
|
||||
private boolean closed;
|
||||
|
||||
public OpenHABHome(BridgeSettings bridgeSettings) {
|
||||
super();
|
||||
closed = true;
|
||||
createHome(bridgeSettings);
|
||||
closed = false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String deviceHandler(CallItem anItem, MultiCommandUtil aMultiUtil, String lightId, int intensity,
|
||||
Integer targetBri, Integer targetBriInc, ColorData colorData, DeviceDescriptor device, String body) {
|
||||
|
||||
String theUrl = anItem.getItem().getAsString();
|
||||
String responseString = null;
|
||||
|
||||
if(theUrl != null && !theUrl.isEmpty()) {
|
||||
OpenHABCommand theCommand = null;
|
||||
try {
|
||||
if(anItem.getItem().isJsonObject())
|
||||
theCommand = new Gson().fromJson(anItem.getItem(), OpenHABCommand.class);
|
||||
else
|
||||
theCommand = new Gson().fromJson(anItem.getItem().getAsString().replaceAll("^\"|\"$", ""), OpenHABCommand.class);
|
||||
} catch(Exception e) {
|
||||
log.warn("Cannot parse command to OpenHAB <<<" + theUrl + ">>>", e);
|
||||
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
|
||||
"Error on calling url to change device state", "/lights/"
|
||||
+ lightId + "/state", null, null).getTheErrors(), HueError[].class);
|
||||
return responseString;
|
||||
}
|
||||
String intermediate = theCommand.getUrl().substring(theCommand.getUrl().indexOf("://") + 3);
|
||||
String hostPortion = intermediate.substring(0, intermediate.indexOf('/'));
|
||||
String theUrlBody = intermediate.substring(intermediate.indexOf('/') + 1);
|
||||
String hostAddr = null;
|
||||
if (hostPortion.contains(":")) {
|
||||
hostAddr = hostPortion.substring(0, intermediate.indexOf(':'));
|
||||
} else
|
||||
hostAddr = hostPortion;
|
||||
OpenHABInstance theHandler = findHandlerByAddress(hostAddr);
|
||||
if(theHandler != null) {
|
||||
String anUrl = BrightnessDecode.calculateReplaceIntensityValue(theUrlBody,
|
||||
intensity, targetBri, targetBriInc, false);
|
||||
if (colorData != null) {
|
||||
anUrl = ColorDecode.replaceColorData(anUrl, colorData, BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc), false);
|
||||
}
|
||||
anUrl = DeviceDataDecode.replaceDeviceData(anUrl, device);
|
||||
anUrl = TimeDecode.replaceTimeValue(anUrl);
|
||||
|
||||
String aCommand = null;
|
||||
if(theCommand.getCommand() != null && !theCommand.getCommand().isEmpty()) {
|
||||
aCommand = BrightnessDecode.calculateReplaceIntensityValue(theCommand.getCommand(),
|
||||
intensity, targetBri, targetBriInc, false);
|
||||
if (colorData != null) {
|
||||
aCommand = ColorDecode.replaceColorData(aCommand, colorData, BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc), false);
|
||||
}
|
||||
aCommand = DeviceDataDecode.replaceDeviceData(aCommand, device);
|
||||
aCommand = TimeDecode.replaceTimeValue(aCommand);
|
||||
}
|
||||
try {
|
||||
boolean success = theHandler.callCommand(anUrl, aCommand, httpClient);
|
||||
if(!success) {
|
||||
log.warn("Comand had error to OpenHAB");
|
||||
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
|
||||
"Error on calling url to change device state", "/lights/"
|
||||
+ lightId + "state", null, null).getTheErrors(), HueError[].class);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("Cannot send comand to OpenHAB", e);
|
||||
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
|
||||
"Error on calling url to change device state", "/lights/"
|
||||
+ lightId + "state", null, null).getTheErrors(), HueError[].class);
|
||||
}
|
||||
} else {
|
||||
log.warn("OpenHAB Call could not complete, no address found: " + theUrl);
|
||||
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
|
||||
"Error on calling url to change device state", "/lights/"
|
||||
+ lightId + "state", null, null).getTheErrors(), HueError[].class);
|
||||
}
|
||||
} else {
|
||||
log.warn("OpenHAB Call to be presented as http(s)://<ip_address>(:<port>)/payload, format of request unknown: " + theUrl);
|
||||
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
|
||||
"Error on calling url to change device state", "/lights/"
|
||||
+ lightId + "state", null, null).getTheErrors(), HueError[].class);
|
||||
}
|
||||
return responseString;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getItems(String type) {
|
||||
|
||||
if(!validOpenhab)
|
||||
return null;
|
||||
log.debug("consolidating devices for OpenHAB");
|
||||
List<OpenHABDevice> theResponse = null;
|
||||
Iterator<String> keys = openhabMap.keySet().iterator();
|
||||
List<OpenHABDevice> deviceList = new ArrayList<OpenHABDevice>();
|
||||
while(keys.hasNext()) {
|
||||
String key = keys.next();
|
||||
theResponse = openhabMap.get(key).getDevices(httpClient);
|
||||
if(theResponse != null)
|
||||
addOpenhabDevices(deviceList, theResponse, key);
|
||||
else {
|
||||
log.warn("Cannot get devices for OpenHAB with name: " + key + ", skipping this OpenHAB.");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return deviceList;
|
||||
}
|
||||
|
||||
private Boolean addOpenhabDevices(List<OpenHABDevice> theDeviceList, List<OpenHABDevice> theSourceList, String theKey) {
|
||||
Iterator<OpenHABDevice> devices = theSourceList.iterator();
|
||||
while(devices.hasNext()) {
|
||||
OpenHABDevice theDevice = devices.next();
|
||||
theDeviceList.add(theDevice);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Home createHome(BridgeSettings bridgeSettings) {
|
||||
openhabMap = null;
|
||||
validOpenhab = bridgeSettings.getBridgeSettingsDescriptor().isValidOpenhab();
|
||||
log.info("OpenHAB Home created." + (validOpenhab ? "" : " No OpenHABs configured."));
|
||||
if(validOpenhab) {
|
||||
openhabMap = new HashMap<String,OpenHABInstance>();
|
||||
httpClient = HTTPHome.getHandler();
|
||||
Iterator<NamedIP> theList = bridgeSettings.getBridgeSettingsDescriptor().getOpenhabaddress().getDevices().iterator();
|
||||
while(theList.hasNext() && validOpenhab) {
|
||||
NamedIP anOpenhab = theList.next();
|
||||
try {
|
||||
openhabMap.put(anOpenhab.getName(), new OpenHABInstance(anOpenhab));
|
||||
} catch (Exception e) {
|
||||
log.error("Cannot get OpenHAB (" + anOpenhab.getName() + ") setup, Exiting with message: " + e.getMessage(), e);
|
||||
validOpenhab = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
private OpenHABInstance findHandlerByAddress(String hostAddress) {
|
||||
OpenHABInstance aHandler = null;
|
||||
boolean found = false;
|
||||
Iterator<String> keys = openhabMap.keySet().iterator();
|
||||
while(keys.hasNext()) {
|
||||
String key = keys.next();
|
||||
aHandler = openhabMap.get(key);
|
||||
if(aHandler != null && aHandler.getOpenHABAddress().getIp().equals(hostAddress)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found)
|
||||
aHandler = null;
|
||||
return aHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeHome() {
|
||||
log.debug("Closing Home.");
|
||||
if(!closed && validOpenhab) {
|
||||
log.debug("Home is already closed....");
|
||||
return;
|
||||
}
|
||||
|
||||
if(httpClient != null)
|
||||
httpClient.closeHandler();
|
||||
|
||||
openhabMap = null;
|
||||
closed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh() {
|
||||
// noop
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package com.bwssystems.HABridge.plugins.openhab;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.bwssystems.HABridge.NamedIP;
|
||||
import com.bwssystems.HABridge.api.NameValue;
|
||||
import com.bwssystems.HABridge.plugins.http.HTTPHandler;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
public class OpenHABInstance {
|
||||
private static final Logger log = LoggerFactory.getLogger(OpenHABInstance.class);
|
||||
private NamedIP theOpenHAB;
|
||||
|
||||
public OpenHABInstance(NamedIP openhabLocation) {
|
||||
super();
|
||||
theOpenHAB = openhabLocation;
|
||||
}
|
||||
|
||||
public NamedIP getOpenHABAddress() {
|
||||
return theOpenHAB;
|
||||
}
|
||||
|
||||
public void setOpenHABAddress(NamedIP openhabAddress) {
|
||||
this.theOpenHAB = openhabAddress;
|
||||
}
|
||||
|
||||
public Boolean callCommand(String aCommand, String commandData, HTTPHandler httpClient) {
|
||||
log.debug("calling OpenHAB: " + theOpenHAB.getIp() + ":" + theOpenHAB.getPort() + aCommand);
|
||||
String aUrl = null;
|
||||
if(theOpenHAB.getSecure() != null && theOpenHAB.getSecure())
|
||||
aUrl = "https://";
|
||||
else
|
||||
aUrl = "http://";
|
||||
|
||||
aUrl = aUrl + theOpenHAB.getIp() + ":" + theOpenHAB.getPort() + "/" + aCommand;
|
||||
String theData = httpClient.doHttpRequest(aUrl, HttpPost.METHOD_NAME, "text/plain", commandData, httpClient.addBasicAuthHeader(null, theOpenHAB));
|
||||
log.debug("call Command return is: <" + theData + ">");
|
||||
if(theData.contains("error") || theData.contains("ERROR") || theData.contains("Error"))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public List<OpenHABDevice> getDevices(HTTPHandler httpClient) {
|
||||
List<OpenHABDevice> deviceList = null;
|
||||
OpenHABItem[] theOpenhabStates;
|
||||
String theUrl = null;
|
||||
String theData;
|
||||
NameValue[] headers = null;
|
||||
if(theOpenHAB.getSecure() != null && theOpenHAB.getSecure())
|
||||
theUrl = "https://";
|
||||
else
|
||||
theUrl = "http://";
|
||||
if(theOpenHAB.getUsername() != null && !theOpenHAB.getUsername().isEmpty() && theOpenHAB.getPassword() != null && !theOpenHAB.getPassword().isEmpty()) {
|
||||
theUrl = theUrl + theOpenHAB.getUsername() + ":" + theOpenHAB.getPassword() + "@";
|
||||
}
|
||||
theUrl = theUrl + theOpenHAB.getIp() + ":" + theOpenHAB.getPort() + "/rest/items?recursive=false";
|
||||
theData = httpClient.doHttpRequest(theUrl, HttpGet.METHOD_NAME, "application/json", null, headers);
|
||||
if(theData != null) {
|
||||
log.debug("GET OpenHAB States - data: " + theData);
|
||||
try {
|
||||
theOpenhabStates = new Gson().fromJson(theData, OpenHABItem[].class);
|
||||
if(theOpenhabStates == null) {
|
||||
log.warn("Cannot get any devices for OpenHAB " + theOpenHAB.getName() + " as response is not parsable.");
|
||||
}
|
||||
else {
|
||||
deviceList = new ArrayList<OpenHABDevice>();
|
||||
|
||||
for (int i = 0; i < theOpenhabStates.length; i++) {
|
||||
OpenHABDevice aNewOpenHABDeviceDevice = new OpenHABDevice();
|
||||
aNewOpenHABDeviceDevice.setItem(theOpenhabStates[i]);
|
||||
aNewOpenHABDeviceDevice.setAddress(theOpenHAB.getIp() + ":" + theOpenHAB.getPort());
|
||||
aNewOpenHABDeviceDevice.setName(theOpenHAB.getName());
|
||||
deviceList.add(aNewOpenHABDeviceDevice);
|
||||
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("Cannot get an devices for OpenHAB " + theOpenHAB.getName() + " Gson Parse Error.");
|
||||
}
|
||||
}
|
||||
else
|
||||
log.warn("Cannot get an devices for OpenHAB " + theOpenHAB.getName() + " http call failed.");
|
||||
return deviceList;
|
||||
}
|
||||
|
||||
|
||||
protected void closeClient() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
|
||||
package com.bwssystems.HABridge.plugins.openhab;
|
||||
|
||||
import java.util.List;
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class OpenHABItem {
|
||||
|
||||
@SerializedName("link")
|
||||
@Expose
|
||||
private String link;
|
||||
@SerializedName("state")
|
||||
@Expose
|
||||
private String state;
|
||||
@SerializedName("type")
|
||||
@Expose
|
||||
private String type;
|
||||
@SerializedName("name")
|
||||
@Expose
|
||||
private String name;
|
||||
@SerializedName("label")
|
||||
@Expose
|
||||
private String label;
|
||||
@SerializedName("category")
|
||||
@Expose
|
||||
private String category;
|
||||
@SerializedName("tags")
|
||||
@Expose
|
||||
private List<Object> tags = null;
|
||||
@SerializedName("groupNames")
|
||||
@Expose
|
||||
private List<Object> groupNames = null;
|
||||
@SerializedName("stateDescription")
|
||||
@Expose
|
||||
private StateDescription stateDescription;
|
||||
|
||||
public String getLink() {
|
||||
return link;
|
||||
}
|
||||
|
||||
public void setLink(String link) {
|
||||
this.link = link;
|
||||
}
|
||||
|
||||
public String getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(String state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
public void setLabel(String label) {
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public String getCategory() {
|
||||
return category;
|
||||
}
|
||||
|
||||
public void setCategory(String category) {
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
public List<Object> getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
public void setTags(List<Object> tags) {
|
||||
this.tags = tags;
|
||||
}
|
||||
|
||||
public List<Object> getGroupNames() {
|
||||
return groupNames;
|
||||
}
|
||||
|
||||
public void setGroupNames(List<Object> groupNames) {
|
||||
this.groupNames = groupNames;
|
||||
}
|
||||
|
||||
public StateDescription getStateDescription() {
|
||||
return stateDescription;
|
||||
}
|
||||
|
||||
public void setStateDescription(StateDescription stateDescription) {
|
||||
this.stateDescription = stateDescription;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
|
||||
package com.bwssystems.HABridge.plugins.openhab;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class Option {
|
||||
|
||||
@SerializedName("value")
|
||||
@Expose
|
||||
private String value;
|
||||
@SerializedName("label")
|
||||
@Expose
|
||||
private String label;
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
public void setLabel(String label) {
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
|
||||
package com.bwssystems.HABridge.plugins.openhab;
|
||||
|
||||
import java.util.List;
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class StateDescription {
|
||||
|
||||
@SerializedName("pattern")
|
||||
@Expose
|
||||
private String pattern;
|
||||
@SerializedName("readOnly")
|
||||
@Expose
|
||||
private Boolean readOnly;
|
||||
@SerializedName("options")
|
||||
@Expose
|
||||
private List<Option> options = null;
|
||||
|
||||
public String getPattern() {
|
||||
return pattern;
|
||||
}
|
||||
|
||||
public void setPattern(String pattern) {
|
||||
this.pattern = pattern;
|
||||
}
|
||||
|
||||
public Boolean getReadOnly() {
|
||||
return readOnly;
|
||||
}
|
||||
|
||||
public void setReadOnly(Boolean readOnly) {
|
||||
this.readOnly = readOnly;
|
||||
}
|
||||
|
||||
public List<Option> getOptions() {
|
||||
return options;
|
||||
}
|
||||
|
||||
public void setOptions(List<Option> options) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -72,26 +72,26 @@ public class SomfyHome implements Home {
|
||||
log.warn("Should not get here, no somfy hub available");
|
||||
responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
|
||||
+ "\",\"description\": \"Should not get here, no somfy hub available\", \"parameter\": \"/lights/"
|
||||
+ lightId + "state\"}}]";
|
||||
+ lightId + "/state\"}}]";
|
||||
} else {
|
||||
if (anItem.getType() != null && anItem.getType().trim().equalsIgnoreCase(DeviceMapTypes.SOMFY_DEVICE[DeviceMapTypes.typeIndex])) {
|
||||
|
||||
log.debug("executing HUE api request to change activity to Somfy: " + anItem.getItem().toString());
|
||||
String jsonToPost = anItem.getItem().toString();
|
||||
String jsonToPost = anItem.getItem().getAsString().replaceAll("^\"|\"$", "");
|
||||
log.debug("executing HUE api request to change activity to Somfy: {}", jsonToPost);
|
||||
|
||||
SomfyInfo somfyHandler = getSomfyHandler(device.getTargetDevice());
|
||||
if(somfyHandler == null) {
|
||||
log.warn("Should not get here, no Somfy configured");
|
||||
responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
|
||||
+ "\",\"description\": \"Should not get here, no somfy configured\", \"parameter\": \"/lights/"
|
||||
+ lightId + "state\"}}]";
|
||||
+ lightId + "/state\"}}]";
|
||||
} else {
|
||||
try {
|
||||
somfyHandler.execApply(jsonToPost);
|
||||
} catch (Exception e) {
|
||||
log.warn("Error posting request to Somfy");
|
||||
responseString = "[{\"error\":{\"type\": 6, \"address\": \"/lights/" + lightId
|
||||
+ "\",\"description\": \"Error posting request to SomfyTahoma\", \"parameter\": \"/lights/" + lightId + "state\"}}]";
|
||||
+ "\",\"description\": \"Error posting request to SomfyTahoma\", \"parameter\": \"/lights/" + lightId + "/state\"}}]";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -103,7 +103,7 @@ public class SomfyHome implements Home {
|
||||
@Override
|
||||
public Home createHome(BridgeSettings bridgeSettings) {
|
||||
validSomfy = bridgeSettings.getBridgeSettingsDescriptor().isValidSomfy();
|
||||
log.info("Somfy Home created." + (validSomfy ? "" : " No Somfys configured."));
|
||||
log.info("Somfy Home created. {}", (validSomfy ? "" : " No Somfys configured."));
|
||||
if(validSomfy) {
|
||||
somfys = new HashMap<>();
|
||||
Iterator<NamedIP> theList = bridgeSettings.getBridgeSettingsDescriptor().getSomfyAddress().getDevices().iterator();
|
||||
@@ -125,4 +125,9 @@ public class SomfyHome implements Home {
|
||||
somfys = null;
|
||||
closed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh() {
|
||||
// noop
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,8 +74,8 @@ public class SomfyInfo {
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
urlEncodedFormEntity.writeTo(bos);
|
||||
String body = bos.toString();
|
||||
String response = httpClient.doHttpRequest(BASE_URL + "json/login",HttpPost.METHOD_NAME, "application/x-www-form-urlencoded", body,httpHeader);
|
||||
log.debug(response);
|
||||
String response = httpClient.doHttpRequest(BASE_URL + "json/login", HttpPost.METHOD_NAME, "application/x-www-form-urlencoded", body,httpHeader);
|
||||
log.debug("Somfy login response <<<{}>>>", response);
|
||||
}
|
||||
|
||||
private NameValue[] getHttpHeaders() {
|
||||
@@ -89,16 +89,16 @@ public class SomfyInfo {
|
||||
NameValue[] httpHeader = getHttpHeaders();
|
||||
log.info("Making SOMFY http setup call");
|
||||
String response = httpClient.doHttpRequest(BASE_URL + "json/getSetup", HttpGet.METHOD_NAME, "", "", httpHeader );
|
||||
log.debug(response);
|
||||
log.debug("Somfy getSetup response <<<{}>>>", response);
|
||||
GetSetup setupData = new Gson().fromJson(response, GetSetup.class);
|
||||
return setupData;
|
||||
}
|
||||
|
||||
public void execApply(String jsonToPost) throws Exception {
|
||||
login(namedIP.getUsername(), namedIP.getPassword());
|
||||
log.info("Making SOMFY http exec call");
|
||||
log.info("Making SOMFY http exec call with json: {}", jsonToPost);
|
||||
String response = httpClient.doHttpRequest(BASE_URL_ENDUSER + "exec/apply", HttpPost.METHOD_NAME, "application/json;charset=UTF-8", jsonToPost, getHttpHeaders());
|
||||
log.info(response);
|
||||
log.debug("Somfy exec reply response <<<{}>>>", response);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.xml.bind.DatatypeConverter;
|
||||
import com.bwssystems.HABridge.util.HexLibrary;
|
||||
|
||||
import org.apache.commons.lang3.StringEscapeUtils;
|
||||
import org.slf4j.Logger;
|
||||
@@ -48,7 +48,7 @@ public class TCPHome implements Home {
|
||||
Integer targetBri,Integer targetBriInc, ColorData colorData, DeviceDescriptor device, String body) {
|
||||
Socket dataSendSocket = null;
|
||||
log.debug("executing HUE api request to TCP: " + anItem.getItem().getAsString());
|
||||
String theUrl = anItem.getItem().getAsString();
|
||||
String theUrl = anItem.getItem().getAsString().replaceAll("^\"|\"$", "");
|
||||
|
||||
if(theUrl != null && !theUrl.isEmpty () && theUrl.contains("tcp://")) {
|
||||
if(!theUrl.startsWith("{\"tcpDevice\""))
|
||||
@@ -89,13 +89,19 @@ public class TCPHome implements Home {
|
||||
theUrlBody = ColorDecode.replaceColorData(theUrlBody, colorData, BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc), true);
|
||||
}
|
||||
theUrlBody = DeviceDataDecode.replaceDeviceData(theUrlBody, device);
|
||||
sendData = DatatypeConverter.parseHexBinary(theUrlBody.substring(2));
|
||||
if (colorData != null) {
|
||||
theUrlBody = ColorDecode.replaceColorData(theUrlBody, colorData, BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc), true);
|
||||
}
|
||||
sendData = HexLibrary.decodeHexString(theUrlBody.substring(2));
|
||||
} else {
|
||||
theUrlBody = BrightnessDecode.calculateReplaceIntensityValue(theUrlBody, intensity, targetBri, targetBriInc, false);
|
||||
if (colorData != null) {
|
||||
theUrlBody = ColorDecode.replaceColorData(theUrlBody, colorData, BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc), false);
|
||||
}
|
||||
theUrlBody = DeviceDataDecode.replaceDeviceData(theUrlBody, device);
|
||||
if (colorData != null) {
|
||||
theUrlBody = ColorDecode.replaceColorData(theUrlBody, colorData, BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc), false);
|
||||
}
|
||||
theUrlBody = StringEscapeUtils.unescapeJava(theUrlBody);
|
||||
sendData = theUrlBody.getBytes();
|
||||
}
|
||||
@@ -166,5 +172,9 @@ public class TCPHome implements Home {
|
||||
}
|
||||
closed = true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void refresh() {
|
||||
// noop
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user