Updating color handling

This commit is contained in:
BWS Systems
2019-05-21 16:44:38 -05:00
parent b6b9089ec4
commit 45e2b63f98
5 changed files with 370 additions and 263 deletions

View File

@@ -49,8 +49,6 @@ This bridge was built to help put the Internet of Things together.
## Build ## Build
To customize and build it yourself, build a new jar with maven: To customize and build it yourself, build a new jar with maven:
ATTENTION: This requires JDK 1.8 to build
``` ```
mvn install mvn install
``` ```
@@ -58,30 +56,23 @@ Otherwise, downloads are available at https://github.com/bwssytems/ha-bridge/rel
## Run ## Run
Then locate the jar and start the server with: Then locate the jar and start the server with:
ATTENTION: This requires JDK 1.8 to run
ATTENTION: Due to port 80 being the default, Linux restricts this to super user. Use the instructions below. ATTENTION: Due to port 80 being the default, Linux restricts this to super user. Use the instructions below.
``` ```
java -jar ha-bridge-5.2.2.jar java -jar ha-bridge-5.3.0.jar
```
ATTENTION: If running Java9, you will need to add the xml bind module
```
java -jar --add-modules java.xml.bind ha-bridge-5.2.2.jar
``` ```
## Manual installation of ha-bridge and setup of systemd service ## Manual installation of ha-bridge and setup of systemd service
Next gen Linux systems (this includes the Raspberry Pi), use systemd to run and manage services. Next gen Linux systems (this includes the Raspberry Pi), use systemd to run and manage services.
Here is a link on how to use systemd: https://www.digitalocean.com/community/tutorials/how-to-use-systemctl-to-manage-systemd-services-and-units Here is a link on how to use systemd: https://www.digitalocean.com/community/tutorials/how-to-use-systemctl-to-manage-systemd-services-and-units
Create the directory and make sure that ha-bridge-5.2.2.jar is in your /home/pi/ha-bridge directory. Create the directory and make sure that ha-bridge-5.3.0.jar is in your /home/pi/ha-bridge directory.
``` ```
pi@raspberrypi:~ $ mkdir ha-bridge pi@raspberrypi:~ $ mkdir ha-bridge
pi@raspberrypi:~ $ cd ha-bridge pi@raspberrypi:~ $ cd ha-bridge
pi@raspberrypi:~/ha-bridge $ wget https://github.com/bwssytems/ha-bridge/releases/download/v5.2.2/ha-bridge-5.2.2.jar pi@raspberrypi:~/ha-bridge $ wget https://github.com/bwssytems/ha-bridge/releases/download/v5.3.0/ha-bridge-5.3.0.jar
``` ```
Create the ha-bridge.service unit file: Create the ha-bridge.service unit file:
@@ -100,7 +91,7 @@ After=network.target
Type=simple Type=simple
WorkingDirectory=/home/pi/ha-bridge WorkingDirectory=/home/pi/ha-bridge
ExecStart=/usr/bin/java -jar -Dconfig.file=/home/pi/ha-bridge/data/habridge.config /home/pi/ha-bridge/ha-bridge-5.2.2.jar ExecStart=/usr/bin/java -jar -Dconfig.file=/home/pi/ha-bridge/data/habridge.config /home/pi/ha-bridge/ha-bridge-5.3.0.jar
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target

255
pom.xml
View File

@@ -1,105 +1,102 @@
<?xml version="1.0" encoding="UTF-8"?> <?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" <project xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 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> <modelVersion>4.0.0</modelVersion>
<groupId>com.bwssystems.HABridge</groupId> <groupId>com.bwssystems.HABridge</groupId>
<artifactId>ha-bridge</artifactId> <artifactId>ha-bridge</artifactId>
<version>5.2.2</version> <version>5.2.next_a</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>HA Bridge</name> <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> <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> <properties>
<java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> </properties>
<repositories> <repositories>
<repository> <repository>
<id>jitpack.io</id> <id>jitpack.io</id>
<url>https://jitpack.io</url> <url>https://jitpack.io</url>
</repository>
<repository>
<id>Eclipse Paho Repo</id>
<url>https://repo.eclipse.org/content/repositories/paho-releases/</url>
</repository> </repository>
<repository>
<id>Eclipse Paho Repo</id>
<url>https://repo.eclipse.org/content/repositories/paho-releases/</url>
</repository>
</repositories> </repositories>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>com.github.bwssytems</groupId> <groupId>com.github.bwssytems</groupId>
<artifactId>harmony-java-client</artifactId> <artifactId>harmony-java-client</artifactId>
<version>master-SNAPSHOT</version> <version>master-SNAPSHOT</version>
<exclusions> <exclusions>
<exclusion> <exclusion>
<groupId>org.slf4j</groupId> <groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId> <artifactId>slf4j-simple</artifactId>
</exclusion> </exclusion>
<exclusion> <exclusion>
<groupId>org.slf4j</groupId> <groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId> <artifactId>log4j-over-slf4j</artifactId>
</exclusion> </exclusion>
</exclusions> </exclusions>
</dependency> </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> <dependency>
<groupId>com.sparkjava</groupId> <groupId>com.github.bwssytems</groupId>
<artifactId>spark-core</artifactId> <artifactId>nest-controller</artifactId>
<version>2.7.2</version> <version>1.0.14</version>
<exclusions> <exclusions>
<exclusion> <exclusion>
<artifactId>slf4j-simple</artifactId> <groupId>org.slf4j</groupId>
<groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId>
</exclusion> </exclusion>
</exclusions> <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>
<dependency> <dependency>
<groupId>org.apache.httpcomponents</groupId> <groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId> <artifactId>httpclient</artifactId>
<version>4.5.1</version> <version>4.5.1</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.httpcomponents</groupId> <groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId> <artifactId>httpcore</artifactId>
<version>4.4.4</version> <version>4.4.4</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.slf4j</groupId> <groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId> <artifactId>slf4j-api</artifactId>
<version>1.7.24</version> <version>1.7.24</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>ch.qos.logback</groupId> <groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId> <artifactId>logback-classic</artifactId>
<version>1.2.1</version> <version>1.2.1</version>
</dependency> </dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.6.2</version>
</dependency>
<dependency> <dependency>
<groupId>net.java.dev.eval</groupId> <groupId>com.google.code.gson</groupId>
<artifactId>eval</artifactId> <artifactId>gson</artifactId>
<version>0.5</version> <version>2.6.2</version>
</dependency>
<dependency>
<groupId>net.java.dev.eval</groupId>
<artifactId>eval</artifactId>
<version>0.5</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.google.inject</groupId> <groupId>com.google.inject</groupId>
@@ -107,68 +104,95 @@
<version>4.1.0</version> <version>4.1.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.igniterealtime.smack</groupId> <groupId>org.igniterealtime.smack</groupId>
<artifactId>smack-core</artifactId> <artifactId>smack-core</artifactId>
<version>4.2.0</version> <version>4.2.0</version>
</dependency>
<dependency>
<groupId>org.eclipse.paho</groupId>
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.github.bwssytems</groupId> <groupId>org.eclipse.paho</groupId>
<artifactId>lifx-sdk-java</artifactId> <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
<version>2.1.6</version> <version>1.2.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.github.mob41</groupId> <groupId>junit</groupId>
<artifactId>broadlink-java-api</artifactId> <artifactId>junit</artifactId>
<version>master-SNAPSHOT</version> <version>4.12</version>
<scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.commons</groupId> <groupId>com.github.bwssytems</groupId>
<artifactId>commons-lang3</artifactId> <artifactId>lifx-sdk-java</artifactId>
<version>3.5</version> <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> </dependency>
</dependencies> </dependencies>
<build> <build>
<resources> <resources>
<resource> <resource>
<directory>src/main/resources</directory> <directory>src/main/resources</directory>
<includes> <includes>
<include>version.properties</include> <include>version.properties</include>
</includes> </includes>
<filtering>true</filtering> <filtering>true</filtering>
</resource> </resource>
<resource> <resource>
<directory>src/main/resources</directory> <directory>src/main/resources</directory>
<excludes> <excludes>
<exclude>version.properties</exclude> <exclude>version.properties</exclude>
</excludes> </excludes>
<filtering>false</filtering> <filtering>false</filtering>
</resource> </resource>
</resources> </resources>
<plugins> <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> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId> <artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version> <version>3.0.0-M3</version>
<configuration> <configuration>
<skipTests>true</skipTests> <skipTests>true</skipTests>
</configuration> </configuration>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId> <artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version> <version>3.2.1</version>
<executions> <executions>
<execution> <execution>
<phase>package</phase> <phase>package</phase>
@@ -230,8 +254,7 @@
</filter> </filter>
</filters> </filters>
<transformers> <transformers>
<transformer <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.bwssystems.HABridge.HABridge</mainClass> <mainClass>com.bwssystems.HABridge.HABridge</mainClass>
</transformer> </transformer>
</transformers> </transformers>

View File

@@ -18,6 +18,7 @@ import org.slf4j.LoggerFactory;
import com.bwssystems.HABridge.DeviceMapTypes; import com.bwssystems.HABridge.DeviceMapTypes;
import com.bwssystems.HABridge.api.CallItem; import com.bwssystems.HABridge.api.CallItem;
import com.bwssystems.HABridge.api.hue.DeviceResponse; import com.bwssystems.HABridge.api.hue.DeviceResponse;
import com.bwssystems.HABridge.api.hue.DeviceState;
import com.bwssystems.HABridge.dao.DeviceDescriptor; import com.bwssystems.HABridge.dao.DeviceDescriptor;
import com.bwssystems.HABridge.plugins.hue.HueHome; import com.bwssystems.HABridge.plugins.hue.HueHome;
import com.bwssystems.HABridge.util.BackupHandler; import com.bwssystems.HABridge.util.BackupHandler;
@@ -67,7 +68,10 @@ public class DeviceRepository extends BackupHandler {
{ {
DeviceDescriptor list[] = gson.fromJson(jsonContent, DeviceDescriptor[].class); DeviceDescriptor list[] = gson.fromJson(jsonContent, DeviceDescriptor[].class);
for(int i = 0; i < list.length; i++) { for(int i = 0; i < list.length; i++) {
list[i].setDeviceState(null); 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]); 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()); nextId = Integer.decode(list[i].getId());

View File

@@ -4,8 +4,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.awt.Color; import java.awt.Color;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -24,91 +23,174 @@ public class ColorDecode {
private static final String COLOR_HSL = "${color.hsl}"; private static final String COLOR_HSL = "${color.hsl}";
private static final Pattern COLOR_MILIGHT = Pattern.compile("\\$\\{color.milight\\:([01234])\\}"); private static final Pattern COLOR_MILIGHT = Pattern.compile("\\$\\{color.milight\\:([01234])\\}");
public static List<Integer> convertHSLtoRGB(int hue, int sat, int brightness) {
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(brightness > 0)
decimalBrightness = (float) (brightness / 255.0);
if(hue > 0) {
h = (float)(hue / 65535.0);
h2 = h + (float)0.5;
if(h2 > 1) {
h2 = h2 * (float) -1.0;
}
}
if(sat > 0) {
s = (float)(sat / 254.0);
}
if (s == 0)
{
r = decimalBrightness * 255;
g = decimalBrightness * 255;
b = decimalBrightness * 255;
}
else
{
if (decimalBrightness < 0.5)
{
var_2 = decimalBrightness * (1 + s);
}
else
{
var_2 = (decimalBrightness + s) - (s * decimalBrightness);
};
var_1 = 2 * decimalBrightness - var_2;
r = 255 * hue_2_rgb(var_1,var_2,h2 + (1 / 3));
g = 255 * hue_2_rgb(var_1,var_2,h2);
b = 255 * hue_2_rgb(var_1,var_2,h2 - (1 / 3));
};
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));
return rgb;
}
public static float hue_2_rgb(float v1, float v2, float vh) {
if (vh < 0)
{
vh += 1;
};
if (vh > 1)
{
vh -= 1;
};
if ((6 * vh) < 1)
{
return (v1 + (v2 - v1) * 6 * vh);
};
if ((2 * vh) < 1)
{
return (v2);
};
if ((3 * vh) < 2)
{
return (v1 + (v2 - v1) * ((2 / 3 - vh) * 6));
};
return (v1);
}
public static List<Integer> convertCIEtoRGB(List<Double> xy, int brightness) { public static List<Integer> convertCIEtoRGB(List<Double> xy, int brightness) {
List<Integer> rgb; List<Integer> rgb;
double x = xy.get(0); // the given x value double x = xy.get(0); // the given x value
double y = xy.get(1); // the given y value double y = xy.get(1); // the given y value
double z = 1.0 - x - y; 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 X = (Y / y) * x;
double Z = (Y / y) * z; 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 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) { if (r > b && r > g && r > 1.0) {
g = g / r; g = g / r;
b = b / r; b = b / r;
r = 1.0; r = 1.0;
} } else if (g > b && g > r && g > 1.0) {
else if (g > b && g > r && g > 1.0) {
r = r / g; r = r / g;
b = b / g; b = b / g;
g = 1.0; g = 1.0;
} } else if (b > r && b > g && b > 1.0) {
else if (b > r && b > g && b > 1.0) {
r = r / b; r = r / b;
g = g / b; g = g / b;
b = 1.0; b = 1.0;
} }
r = r <= 0.0031308 ? 12.92 * r : (1.0 + 0.055) * Math.pow(r, (1.0 / 2.4)) - 0.055; 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; 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; 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>(); if (r > b && r > g) {
rgb.add((int)Math.round(r * 255)); // red is biggest
rgb.add((int)Math.round(g * 255)); if (r > 1.0) {
rgb.add((int)Math.round(b * 255)); g = g / r;
log.debug("Color change with XY: " + x + " " + y + " Resulting RGB Values: " + rgb.get(0) + " " + rgb.get(1) + " " + rgb.get(2)); 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; 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) { public static List<Integer> convertCTtoRGB(Integer ct) {
double temperature = 1000000.0 / (double)ct; double temperature = 1000000.0 / (double) ct;
temperature /= 100; temperature /= 100;
double r,g,b; double r, g, b;
if (temperature <= 66) { if (temperature <= 66) {
r = 255; r = 255;
g = temperature; g = temperature;
g = 99.4708025861 * Math.log(g) - 161.1195681661; g = 99.4708025861 * Math.log(g) - 161.1195681661;
} else { } else {
r = temperature - 60; r = temperature - 60;
r = 329.698727446 * (Math.pow(r, -0.1332047592)); r = 329.698727446 * (Math.pow(r, -0.1332047592));
@@ -126,25 +208,26 @@ public class ColorDecode {
b = 138.5177312231 * Math.log(b) - 305.0447927307; b = 138.5177312231 * Math.log(b) - 305.0447927307;
} }
} }
r = assureBounds(r); r = assureBounds(r);
g = assureBounds(g); g = assureBounds(g);
b = assureBounds(b); b = assureBounds(b);
List<Integer> rgb = new ArrayList<Integer>(); List<Integer> rgb = new ArrayList<Integer>();
rgb.add((int)Math.round(r)); rgb.add((int) Math.round(r));
rgb.add((int)Math.round(g)); rgb.add((int) Math.round(g));
rgb.add((int)Math.round(b)); 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)); log.debug("Color change with CT: " + ct + ". Resulting RGB Values: " + rgb.get(0) + " " + rgb.get(1) + " "
return rgb; + rgb.get(2));
return rgb;
} }
private static double assureBounds(double value) { private static double assureBounds(double value) {
if (value < 0.0) { if (value < 0.0) {
value = 0; value = 0;
} }
if (value > 255.0) { if (value > 255.0) {
value = 255; value = 255;
} }
return value; return value;
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@@ -159,25 +242,28 @@ public class ColorDecode {
ColorData.ColorMode colorMode = colorData.getColorMode(); ColorData.ColorMode colorMode = colorData.getColorMode();
List<Integer> rgb = null; List<Integer> rgb = null;
if (colorMode == ColorData.ColorMode.XY) { 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) { } else if (colorMode == ColorData.ColorMode.CT) {
rgb = convertCTtoRGB((Integer)colorData.getData()); rgb = convertCTtoRGB((Integer) colorData.getData());
} }
while(notDone) { while (notDone) {
notDone = false; notDone = false;
if (request.contains(COLOR_R)) { 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; notDone = true;
} }
if (request.contains(COLOR_G)) { 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; notDone = true;
} }
if (request.contains(COLOR_B)) { 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; notDone = true;
} }
@@ -197,75 +283,78 @@ public class ColorDecode {
} }
if (request.contains(COLOR_RGBX)) { 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; notDone = true;
} }
if (request.contains(COLOR_HSL)) { if (request.contains(COLOR_HSL)) {
float[] hsb = new float[3]; float[] hsb = new float[3];
Color.RGBtoHSB(rgb.get(0),rgb.get(1),rgb.get(2),hsb); Color.RGBtoHSB(rgb.get(0), rgb.get(1), rgb.get(2), hsb);
float hue = hsb[0] * (float) 360.0; float hue = hsb[0] * (float) 360.0;
float sat = hsb[1] * (float) 100.0; float sat = hsb[1] * (float) 100.0;
float bright = hsb[2] * (float) 100.0; float bright = hsb[2] * (float) 100.0;
request = request.replace(COLOR_HSL, String.format("%f,%f,%f", hue, sat, bright)); request = request.replace(COLOR_HSL, String.format("%f,%f,%f", hue, sat, bright));
notDone = true; notDone = true;
} }
Matcher m = COLOR_MILIGHT.matcher(request); Matcher m = COLOR_MILIGHT.matcher(request);
while (m.find()) { while (m.find()) {
int group = Integer.parseInt(m.group(1)); int group = Integer.parseInt(m.group(1));
request = m.replaceFirst(getMilightV5FromRgb(rgb, group)); request = m.replaceFirst(getMilightV5FromRgb(rgb, group));
m.reset(request); m.reset(request);
} }
log.debug("Request <<" + request + ">>, not done: " + notDone); log.debug("Request <<" + request + ">>, not done: " + notDone);
} }
return request; return request;
} }
private static String getMilightV5FromRgb(List<Integer> rgb, int group) { private static String getMilightV5FromRgb(List<Integer> rgb, int group) {
double r = (double)rgb.get(0); double r = (double) rgb.get(0);
double g = (double)rgb.get(1); double g = (double) rgb.get(1);
double b = (double)rgb.get(2); double b = (double) rgb.get(2);
if (r > 245 && g > 245 && b > 245) { // it's white if (r > 245 && g > 245 && b > 245) { // it's white
String retVal = ""; String retVal = "";
if (group == 0) { if (group == 0) {
retVal += "C2"; retVal += "C2";
} else if (group == 1) { } else if (group == 1) {
retVal += "C5"; retVal += "C5";
} else if (group == 2) { } else if (group == 2) {
retVal += "C7"; retVal += "C7";
} else if (group == 3) { } else if (group == 3) {
retVal += "C9"; retVal += "C9";
} else if (group == 4) { } else if (group == 4) {
retVal += "CB"; retVal += "CB";
} }
log.debug("Convert RGB to Milight. Result: WHITE. RGB Values: " + rgb.get(0) + " " + rgb.get(1) + " " + rgb.get(2)); log.debug("Convert RGB to Milight. Result: WHITE. RGB Values: " + rgb.get(0) + " " + rgb.get(1) + " "
return retVal + "0055"; + rgb.get(2));
} else { // normal color return retVal + "0055";
r /= (double)0xFF; } else { // normal color
g /= (double)0xFF; r /= (double) 0xFF;
b /= (double)0xFF; g /= (double) 0xFF;
double max = Math.max(Math.max(r, g), b), min = Math.min(Math.min(r, g), b); b /= (double) 0xFF;
double h = 0; double max = Math.max(Math.max(r, g), b), min = Math.min(Math.min(r, g), b);
double d = max - min; double h = 0;
double d = max - min;
if (max == min) { if (max == min) {
h = 0; h = 0;
} else { } else {
if (max == r) { if (max == r) {
h = ((g - b) / d + (g < b ? 6 : 0)); h = ((g - b) / d + (g < b ? 6 : 0));
} else if (max == g) { } else if (max == g) {
h = ((b - r) / d + 2); h = ((b - r) / d + 2);
} else if (max == b){ } else if (max == b) {
h = ((r - g) / d + 4); h = ((r - g) / d + 4);
} }
h = Math.round(h * 60); h = Math.round(h * 60);
} }
int milight = (int)((256 + 176 - Math.floor(h / 360.0 * 255.0)) % 256); 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)); log.debug("Convert RGB to Milight. Result: " + milight + " RGB Values: " + rgb.get(0) + " " + rgb.get(1)
return "40" + String.format("%02X", milight) + "55"; + " " + rgb.get(2));
} return "40" + String.format("%02X", milight) + "55";
}
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")

View File

@@ -600,8 +600,8 @@ public class HueMulator {
if((deviceState != null) && deviceState.isOn() && deviceState.getBri() <= 0) if((deviceState != null) && deviceState.isOn() && deviceState.getBri() <= 0)
deviceState.setBri(254); deviceState.setBri(254);
if((deviceState != null) && !deviceState.isOn() && (targetBri != null || targetBriInc != null)) // if((deviceState != null) && !deviceState.isOn() && (targetBri != null || targetBriInc != null))
deviceState.setOn(true); // deviceState.setOn(true);
responseString = responseString + "]"; responseString = responseString + "]";
@@ -1186,11 +1186,11 @@ public class HueMulator {
isOnRequest = true; isOnRequest = true;
} }
if(!device.isOnFirstDim() && device.isOnWhenDimPresent() && isDimRequest) { if(!device.isOnFirstDim() && device.isOnWhenDimPresent() && isDimRequest && !isOnRequest) {
isOnRequest = true; isOnRequest = true;
theStateChanges.setOn(true); theStateChanges.setOn(true);
} else if(!device.isOnFirstDim() && !device.isOnWhenDimPresent() && isDimRequest) { } else if(!device.isOnFirstDim() && !device.isOnWhenDimPresent() && isDimRequest) {
isOnRequest = false; // isOnRequest = false;
} }
if(device.isOnFirstDim() && isDimRequest && !device.getDeviceState().isOn()) { if(device.isOnFirstDim() && isDimRequest && !device.getDeviceState().isOn()) {