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
To customize and build it yourself, build a new jar with maven:
ATTENTION: This requires JDK 1.8 to build
```
mvn install
```
@@ -58,30 +56,23 @@ Otherwise, downloads are available at https://github.com/bwssytems/ha-bridge/rel
## Run
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.
```
java -jar ha-bridge-5.2.2.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
java -jar ha-bridge-5.3.0.jar
```
## 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.
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:~ $ 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:
@@ -100,7 +91,7 @@ After=network.target
Type=simple
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]
WantedBy=multi-user.target

43
pom.xml
View File

@@ -1,20 +1,17 @@
<?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.2.2</version>
<version>5.2.next_a</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>
</properties>
@@ -157,10 +154,37 @@
</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>2.22.1</version>
<version>3.0.0-M3</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
@@ -168,7 +192,7 @@
<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>
@@ -230,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>

View File

@@ -18,6 +18,7 @@ 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;
@@ -67,7 +68,10 @@ public class DeviceRepository extends BackupHandler {
{
DeviceDescriptor list[] = gson.fromJson(jsonContent, DeviceDescriptor[].class);
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]);
if(Integer.decode(list[i].getId()) > nextId) {
nextId = Integer.decode(list[i].getId());

View File

@@ -6,7 +6,6 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.awt.Color;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -24,12 +23,98 @@ public class ColorDecode {
private static final String COLOR_HSL = "${color.hsl}";
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) {
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;
@@ -42,21 +127,18 @@ public class ColorDecode {
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;
@@ -68,16 +150,14 @@ public class ColorDecode {
b = b / r;
r = 1.0;
}
}
else if (g > b && g > r) {
} 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) {
} else if (b > r && b > g) {
// blue is biggest
if (b > 1.0) {
r = r / b;
@@ -85,26 +165,28 @@ public class ColorDecode {
b = 1.0;
}
}
if(r < 0.0)
if (r < 0.0)
r = 0;
if(g < 0.0)
if (g < 0.0)
g = 0;
if(b < 0.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));
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;
@@ -130,10 +212,11 @@ public class ColorDecode {
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));
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;
}
@@ -159,25 +242,28 @@ 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());
}
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;
}
@@ -197,13 +283,14 @@ 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);
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;
@@ -224,9 +311,9 @@ public class ColorDecode {
}
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);
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) {
@@ -240,12 +327,13 @@ public class ColorDecode {
} 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));
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;
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;
@@ -257,13 +345,14 @@ public class ColorDecode {
h = ((g - b) / d + (g < b ? 6 : 0));
} else if (max == g) {
h = ((b - r) / d + 2);
} else if (max == b){
} 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));
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";
}
}

View File

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