Compare commits

...

2 Commits

Author SHA1 Message Date
bwssystems
675e74df7b Add switch for dim when color request is present and other items 2020-12-08 17:03:24 -06:00
bwssystems
fb7aabb780 Fix all color handling and dim with no on request 2020-12-07 18:07:42 -06:00
16 changed files with 475 additions and 187 deletions

View File

@@ -57,20 +57,20 @@ Then locate the jar and start the server with:
ATTENTION: Due to port 80 being the default, Linux restricts this to super user. Use the instructions below.
```
java -jar ha-bridge-5.3.1RC3.jar
java -jar ha-bridge-5.3.1RC5.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.3.1RC3.jar is in your /home/pi/ha-bridge directory.
Create the directory and make sure that ha-bridge-5.3.1RC5.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.3.1RC3/ha-bridge-5.3.1RC3.jar
pi@raspberrypi:~/ha-bridge $ wget https://github.com/bwssytems/ha-bridge/releases/download/v5.3.1RC5/ha-bridge-5.3.1RC5.jar
```
Create the ha-bridge.service unit file:
@@ -89,7 +89,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.3.1RC3.jar
ExecStart=/usr/bin/java -jar -Dconfig.file=/home/pi/ha-bridge/data/habridge.config /home/pi/ha-bridge/ha-bridge-5.3.1RC5.jar
[Install]
WantedBy=multi-user.target

View File

@@ -5,7 +5,7 @@
<groupId>com.bwssystems.HABridge</groupId>
<artifactId>ha-bridge</artifactId>
<version>5.3.1RC3</version>
<version>5.3.1RC5-java11</version>
<packaging>jar</packaging>
<name>HA Bridge</name>

View File

@@ -200,7 +200,10 @@ public class BridgeSettings extends BackupHandler {
theBridgeSettings.setNumberoflogmessages(Integer.valueOf(Configuration.NUMBER_OF_LOG_MESSAGES));
if(theBridgeSettings.getButtonsleep() == null || theBridgeSettings.getButtonsleep() < 0)
theBridgeSettings.setButtonsleep(Integer.parseInt(Configuration.DEFAULT_BUTTON_SLEEP));
theBridgeSettings.setButtonsleep(Integer.parseInt(Configuration.DEFAULT_BUTTON_SLEEP));
if(theBridgeSettings.getLinkbuttontimeout() < 30)
theBridgeSettings.setLinkbuttontimeout(Configuration.LINK_BUTTON_TIMEOUT);
theBridgeSettings.setVeraconfigured(theBridgeSettings.isValidVera());
theBridgeSettings.setFibaroconfigured(theBridgeSettings.isValidFibaro());

View File

@@ -135,6 +135,10 @@ public class BridgeSettingsDescriptor {
@SerializedName("upnpadvanced")
@Expose
private boolean upnpadvanced;
@SerializedName("linkbuttontimeout")
@Expose
private Integer linkbuttontimeout;
// @SerializedName("activeloggers")
// @Expose
// private List<NameValue> activeloggers;
@@ -197,6 +201,7 @@ public class BridgeSettingsDescriptor {
this.haaddressessecured = false;
this.configfile = Configuration.CONFIG_FILE;
this.upnpadvanced = false;
this.linkbuttontimeout = Configuration.LINK_BUTTON_TIMEOUT;
}
public String getUpnpConfigAddress() {
@@ -860,4 +865,12 @@ public class BridgeSettingsDescriptor {
public void setUpnpadvanced(boolean upnpadvanced) {
this.upnpadvanced = upnpadvanced;
}
public Integer getLinkbuttontimeout() {
return linkbuttontimeout;
}
public void setLinkbuttontimeout(Integer linkbuttontimeout) {
this.linkbuttontimeout = linkbuttontimeout;
}
}

View File

@@ -17,4 +17,5 @@ public class Configuration {
public static final int UPNP_SEND_DELAY = 650;
public static final int BROADLINK_DISCOVER_PORT = 40000;
public static final int BROADLINK_DISCONVER_TIMEOUT = 5000;
public static final int LINK_BUTTON_TIMEOUT = 45;
}

View File

@@ -276,12 +276,12 @@ public class SystemControl {
if(!request.body().isEmpty()) {
linkParams = new Gson().fromJson(request.body(), LinkParams.class);
if(linkParams.getSeconds() <= 0)
linkParams.setSeconds(1);
linkParams.setSeconds(3);
}
else {
linkParams = new LinkParams();
linkParams.setSilent(false);
linkParams.setSeconds(30);
linkParams.setSeconds(bridgeSettings.getBridgeSettingsDescriptor().getLinkbuttontimeout());
}
if(!linkParams.isSilent())
log.info("Link button pressed....");

View File

@@ -92,7 +92,13 @@ public class DeviceDescriptor{
@SerializedName("startupActions")
@Expose
private String startupActions;
@SerializedName("dimNoOn")
@Expose
private boolean dimNoOn;
@SerializedName("dimOnColor")
@Expose
private boolean dimOnColor;
public String getName() {
return name;
}
@@ -355,4 +361,20 @@ public class DeviceDescriptor{
public void setStartupActions(String startupActions) {
this.startupActions = startupActions;
}
public boolean isDimNoOn() {
return dimNoOn;
}
public void setDimNoOn(boolean dimNoOn) {
this.dimNoOn = dimNoOn;
}
public boolean isDimOnColor() {
return dimOnColor;
}
public void setDimOnColor(boolean dimOnColor) {
this.dimOnColor = dimOnColor;
}
}

View File

@@ -21,6 +21,9 @@ public class BrightnessDecode {
private static final String INTENSITY_MATH_CLOSE_HEX = ").hex}";
private static final String INTENSITY_PERCENT_HEX = "${intensity.percent.hex}";
private static final String INTENSITY_BYTE_HEX = "${intensity.byte.hex}";
private static final String INTENSITY_PREVIOUS_PERCENT = "${intensity.previous_percent}";
private static final String INTENSITY_PREVIOUS_DECIMAL_PERCENT = "${intensity.previous_decimal_percent}";
private static final String INTENSITY_PREVIOUS_BYTE = "${intensity.previous_byte}";
public static int calculateIntensity(int setIntensity, Integer targetBri, Integer targetBriInc) {
if (targetBri != null) {
@@ -45,7 +48,7 @@ public class BrightnessDecode {
* intensity.math(X*1) : where X is the value from the interface call and
* can use net.java.dev.eval math
*/
public static String replaceIntensityValue(String request, int intensity, boolean isHex) {
private static String replaceIntensityValue(String request, int previous_intensity, int intensity, boolean isHex) {
if (request == null) {
return null;
}
@@ -54,6 +57,8 @@ public class BrightnessDecode {
String replaceTarget = null;
int percentBrightness = 0;
float decimalBrightness = (float) 1.0;
int previousPercentBrightness = 0;
float previousDecimalBrightness = (float) 1.0;
Map<String, BigDecimal> variables = new HashMap<String, BigDecimal>();
String mathDescriptor = null;
@@ -68,6 +73,17 @@ public class BrightnessDecode {
percentBrightness = 1;
}
if(previous_intensity > 0) {
previousDecimalBrightness = (float) (previous_intensity / 255.0);
if(previous_intensity > 0 && previous_intensity < 5)
previousPercentBrightness = 1;
else
previousPercentBrightness = (int) Math.round(previous_intensity / 255.0 * 100);
} else {
previousDecimalBrightness = (float) 1.0;
previousPercentBrightness = 1;
}
while(notDone) {
notDone = false;
if (request.contains(INTENSITY_BYTE)) {
@@ -78,6 +94,14 @@ public class BrightnessDecode {
}
replaceTarget = INTENSITY_BYTE;
notDone = true;
} else if (request.contains(INTENSITY_PREVIOUS_BYTE)) {
if (isHex) {
replaceValue = convertToHex(previous_intensity);
} else {
replaceValue = String.valueOf(previous_intensity);
}
replaceTarget = INTENSITY_PREVIOUS_BYTE;
notDone = true;
} else if (request.contains(INTENSITY_BYTE_HEX)) {
replaceValue = convertToHex(intensity);
replaceTarget = INTENSITY_BYTE_HEX;
@@ -90,6 +114,14 @@ public class BrightnessDecode {
}
replaceTarget = INTENSITY_PERCENT;
notDone = true;
} else if (request.contains(INTENSITY_PREVIOUS_PERCENT)) {
if (isHex) {
replaceValue = convertToHex(previousPercentBrightness);
} else {
replaceValue = String.valueOf(previousPercentBrightness);
}
replaceTarget = INTENSITY_PREVIOUS_PERCENT;
notDone = true;
} else if (request.contains(INTENSITY_PERCENT_HEX)) {
replaceValue = convertToHex(percentBrightness);
replaceTarget = INTENSITY_PERCENT_HEX;
@@ -98,6 +130,10 @@ public class BrightnessDecode {
replaceValue = String.format(Locale.ROOT, "%1.2f", decimalBrightness);
replaceTarget = INTENSITY_DECIMAL_PERCENT;
notDone = true;
} else if (request.contains(INTENSITY_PREVIOUS_DECIMAL_PERCENT)) {
replaceValue = String.format(Locale.ROOT, "%1.2f", previousDecimalBrightness);
replaceTarget = INTENSITY_PREVIOUS_DECIMAL_PERCENT;
notDone = true;
} else if (request.contains(INTENSITY_MATH_CLOSE)) {
mathDescriptor = request.substring(request.indexOf(INTENSITY_MATH) + INTENSITY_MATH.length(),
request.indexOf(INTENSITY_MATH_CLOSE));
@@ -135,7 +171,7 @@ public class BrightnessDecode {
// Helper Method
public static String calculateReplaceIntensityValue(String request, int theIntensity, Integer targetBri, Integer targetBriInc, boolean isHex) {
return replaceIntensityValue(request, calculateIntensity(theIntensity, targetBri, targetBriInc), isHex);
return replaceIntensityValue(request, theIntensity, calculateIntensity(theIntensity, targetBri, targetBriInc), isHex);
}
// Apache Commons Conversion utils likes little endian too much

View File

@@ -18,6 +18,8 @@ package com.bwssystems.HABridge.hue;
* XYZ -> CIE-LAB -> XYZ
* @author Diego Catalano
*/
public class ColorConverter {
/**
@@ -26,6 +28,7 @@ public class ColorConverter {
private ColorConverter() {}
public static enum YCbCrColorSpace {ITU_BT_601,ITU_BT_709_HDTV};
private final static double EPSILON = 0.00001;
// XYZ (Tristimulus) Reference values of a perfect reflecting diffuser
@@ -259,7 +262,7 @@ public class ColorConverter {
* @param blue Blue coefficient.
* @return Normalized RGChromaticity. Range[0..1].
*/
public static double[] RGChromaticity(int red, int green, int blue){
public static float[] RGChromaticity(int red, int green, int blue){
double[] color = new double[5];
double sum = red + green + blue;
@@ -276,24 +279,7 @@ public class ColorConverter {
double rS = color[0] - 0.333;
double gS = color[1] - 0.333;
//saturation
color[3] = Math.sqrt(rS * rS + gS * gS);
//hue
color[4] = Math.atan(rS / gS);
return color;
}
/**
* RGB -> HSV.
* Adds (hue + 360) % 360 for represent hue in the range [0..359].
* @param red Red coefficient. Values in the range [0..255].
* @param green Green coefficient. Values in the range [0..255].
* @param blue Blue coefficient. Values in the range [0..255].
* @return HSV color space.
*/
public static float[] RGBtoHSV(int red, int green, int blue){
//saturationBRGBtoHSV(int red, int green, int blue){
float[] hsv = new float[3];
float r = red / 255f;
float g = green / 255f;
@@ -630,69 +616,69 @@ public class ColorConverter {
public static int[] HunterLABtoRGB(float l, float a, float b){
float[] xyz = HunterLABtoXYZ(l, a, b);
return XYZtoRGB(xyz[0], xyz[1], xyz[2]);
}
}
/**
* RGB -> HLS.
* RGB -> HSL.
* @param red Red coefficient. Values in the range [0..255].
* @param green Green coefficient. Values in the range [0..255].
* @param blue Blue coefficient. Values in the range [0..255].
* @return HLS color space.
* @return HSL color space.
*/
public static float[] RGBtoHLS(int red, int green, int blue){
public static float[] RGBtoHSL(int red, int green, int blue){
float[] hsl = new float[3];
float r = red / 255f;
float g = green / 255f;
float b = blue / 255f;
double r = red;
double g = green;
double b = blue;
float max = Math.max(r,Math.max(r,b));
float min = Math.min(r,Math.min(r,b));
float delta = max - min;
double max = Math.max(r,Math.max(g,b));
double min = Math.min(r,Math.min(g,b));
// double delta = max - min;
//HSK
float h = 0;
float s = 0;
float l = (max + min) / 2;
Double h = 0d;
Double s = 0d;
Double l = 0d;
if ( delta == 0 ){
// gray color
h = 0;
s = 0.0f;
}
else
{
// get saturation value
s = ( l <= 0.5 ) ? ( delta / ( max + min ) ) : ( delta / ( 2 - max - min ) );
// get hue value
float hue;
if ( r == max )
{
hue = ( ( g - b ) / 6 ) / delta;
//saturation
double cnt = (max + min) / 2d;
if (cnt <= 127d) {
s = ((max - min) / (max + min));
}
else if ( g == max )
{
hue = ( 1.0f / 3 ) + ( ( b - r ) / 6 ) / delta;
}
else
{
hue = ( 2.0f / 3 ) + ( ( r - g ) / 6 ) / delta;
else {
s = ((max - min) / (510d - max - min));
}
// correct hue if needed
if ( hue < 0 )
hue += 1;
if ( hue > 1 )
hue -= 1;
//lightness
l = ((max + min) / 2d) / 255d;
h = (int) ( hue * 360 );
}
//hue
if (Math.abs(max - min) <= EPSILON) {
h = 0d;
s = 0d;
}
else {
double diff = max - min;
if (Math.abs(max - r) <= EPSILON) {
h = 60d * (g - b) / diff;
}
else if (Math.abs(max - g) <= EPSILON) {
h = 60d * (b - r) / diff + 120d;
}
else {
h = 60d * (r - g) / diff + 240d;
}
if (h < 0d) {
h += 360d;
}
}
hsl[0] = h;
hsl[1] = s;
hsl[2] = l;
hsl[0] = h.floatValue();
hsl[1] = s.floatValue();
hsl[2] = l.floatValue();
return hsl;
}
@@ -931,14 +917,19 @@ public class ColorConverter {
*/
public static float[] XYtoXYZ(XYColorSpace xy){
float[] xyz = new float[3];
/* Old Way
xyz[0] = (xy.getBrightnessAdjusted() / xy.getXy()[1]) * xy.getXy()[0];
xyz[1] = xy.getBrightnessAdjusted();
xyz[2] = (xy.getBrightnessAdjusted() / xy.getXy()[1]) * (1.0f - xy.getXy()[0] - xy.getXy()[1]);
*/
// New Way
xyz[0] = xy.getXy()[0] * (xy.getBrightnessAdjusted() / xy.getXy()[1]) ;
xyz[1] = xy.getBrightnessAdjusted();
xyz[2] = (float) ((1.0 - xy.getXy()[0] - xy.getXy()[1]) * (xy.getBrightnessAdjusted() / xy.getXy()[1]));
return xyz;
}
public static int[] normalizeRGB(int[] rgb) {
int[] newRGB = new int[3];

View File

@@ -4,12 +4,12 @@ import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.awt.Color;
// import java.awt.Color;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.bwssystems.HABridge.hue.ColorData;
// import com.bwssystems.HABridge.hue.ColorData;
public class ColorDecode {
private static final Logger log = LoggerFactory.getLogger(ColorDecode.class);
@@ -27,75 +27,83 @@ public class ColorDecode {
private static final String COLOR_BRI = "${colorbri}";
private static final Pattern COLOR_MILIGHT = Pattern.compile("\\$\\{color.milight\\:([01234])\\}");
public static List<Integer> convertHSBtoRGB(HueSatBri hsb) {
/* This is supersceded by the next iteration function below this original one
public static List<Integer> convertHSBtoRGBOrig(HueSatBri hsb) {
List<Integer> rgb;
Float hue = (Float)(hsb.getHue()*1.0f);
Float saturation = (Float)(hsb.getSat()*1.0f);
Float brightness = (Float)(hsb.getBri()*1.0f);
log.info("Hue = " + hue + ", Sat = " + saturation + ", Bri = " + brightness);
//Convert Hue into degrees for HSB
hue = hue / 182.04f;
// hue = hue / 182.04f;
hue = (hue / 65535.0f) * 360.0f;
//Bri and Sat must be values from 0-1 (~percentage)
brightness = brightness / 255.0f;
saturation = saturation / 255.0f;
// ightness = brightness / 255.0f;
// saturation = saturation / 255.0f;
brightness = brightness / 254.0f;
saturation = saturation / 254.0f;
Float r = 0f;
Float g = 0f;
Float b = 0f;
if (saturation == 0)
{
r = g = b = brightness;
if(brightness > 0.0f) {
if (saturation == 0)
{
r = g = b = brightness;
}
else
{
// the color wheel consists of 6 sectors.
Float sectorPos = hue / 60.0f;
int sectorNumber = (int)(Math.floor(sectorPos));
// get the fractional part of the sector
Float fractionalSector = sectorPos - sectorNumber;
// calculate values for the three axes of the color.
Float p = brightness * (1.0f - saturation);
Float q = brightness * (1.0f - (saturation * fractionalSector));
Float t = brightness * (1.0f - (saturation * (1f - fractionalSector)));
// assign the fractional colors to r, g, and b based on the sector the angle is in.
switch (sectorNumber)
{
case 0:
r = brightness;
g = t;
b = p;
break;
case 1:
r = q;
g = brightness;
b = p;
break;
case 2:
r = p;
g = brightness;
b = t;
break;
case 3:
r = p;
g = q;
b = brightness;
break;
case 4:
r = t;
g = p;
b = brightness;
break;
case 5:
r = brightness;
g = p;
b = q;
break;
}
}
}
else
{
// the color wheel consists of 6 sectors.
Float sectorPos = hue / 60.0f;
int sectorNumber = (int)(Math.floor(sectorPos));
// get the fractional part of the sector
Float fractionalSector = sectorPos - sectorNumber;
// calculate values for the three axes of the color.
Float p = brightness * (1.0f - saturation);
Float q = brightness * (1.0f - (saturation * fractionalSector));
Float t = brightness * (1.0f - (saturation * (1f - fractionalSector)));
// assign the fractional colors to r, g, and b based on the sector the angle is in.
switch (sectorNumber)
{
case 0:
r = brightness;
g = t;
b = p;
break;
case 1:
r = q;
g = brightness;
b = p;
break;
case 2:
r = p;
g = brightness;
b = t;
break;
case 3:
r = p;
g = q;
b = brightness;
break;
case 4:
r = t;
g = p;
b = brightness;
break;
case 5:
r = brightness;
g = p;
b = q;
break;
}
}
//Check if any value is out of byte range
if (r < 0f)
{
@@ -114,10 +122,106 @@ public class ColorDecode {
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 HSB: " + hsb + ". Resulting RGB Values: " + rgb.get(0) + " " + rgb.get(1) + " "
log.info("Color change with HSB: " + hsb + ". Resulting RGB Values: " + rgb.get(0) + " " + rgb.get(1) + " "
+ rgb.get(2));
int theRGB = Color.HSBtoRGB(hue, saturation, brightness);
Color decodedRGB = new Color(theRGB);
log.info("Color change with HSB using java Color: " + hsb + ". Resulting RGB Values: " + decodedRGB.getRed() + " " + decodedRGB.getGreen() + " "
+ decodedRGB.getBlue());
return rgb;
}
*/
public static List<Integer> convertHSBtoRGB(HueSatBri hsb) {
List<Integer> rgb;
Float hue = (Float)(hsb.getHue()*1.0f);
Float saturation = (Float)(hsb.getSat()*1.0f);
Float brightness = (Float)(hsb.getBri()*1.0f);
log.info("Hue = " + hue + ", Sat = " + saturation + ", Bri = " + brightness);
//Convert Hue into degrees for HSB
// hue = hue / 182.04f;
hue = (hue / 65535.0f);
//Bri and Sat must be values from 0-1 (~percentage)
// ightness = brightness / 255.0f;
// saturation = saturation / 255.0f;
brightness = brightness / 254.0f;
saturation = saturation / 254.0f;
Float r = 0f;
Float g = 0f;
Float b = 0f;
Float temp2 = 0f;
Float temp1 = 0f;
if(brightness > 0.0f) {
if (saturation == 0)
{
r = g = b = brightness;
}
else
{
temp2 = (brightness < 0.5f) ? brightness * (1.0f + saturation) : brightness + saturation - (brightness * saturation);
temp1 = 2.0f * brightness - temp2;
r = GetColorComponent(temp1, temp2, hue + 1.0f/3.0f);
g = GetColorComponent(temp1, temp2, hue);
b = GetColorComponent(temp1, temp2, hue - 1.0f/3.0f);
}
}
//Check if any value is out of byte range
if (r < 0f)
{
r = 0f;
}
if (g < 0f)
{
g = 0f;
}
if (b < 0f)
{
b = 0f;
}
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 HSB New: " + hsb + ". Resulting RGB Values: " + rgb.get(0) + " " + rgb.get(1) + " "
+ rgb.get(2));
return rgb;
}
private static Float GetColorComponent(Float temp1, Float temp2, Float temp3)
{
temp3 = MoveIntoRange(temp3);
if (temp3 < 1.0f/6.0f)
{
return temp1 + (temp2 - temp1) * 6.0f * temp3;
}
if (temp3 < 0.5f)
{
return temp2;
}
if (temp3 < 2.0f/3.0f)
{
return temp1 + ((temp2 - temp1) * ((2.0f/3.0f) - temp3) * 6.0f);
}
return temp1;
}
private static Float MoveIntoRange(Float temp3)
{
if (temp3 < 0.0f) return temp3 + 1f;
if (temp3 > 1.0f) return temp3 - 1f;
return temp3;
}
public static List<Integer> convertCIEtoRGB(List<Double> xy, int brightness) {
List<Integer> rgb;
@@ -133,7 +237,7 @@ public class ColorDecode {
rgb.add(rgbInt[0]);
rgb.add(rgbInt[1]);
rgb.add(rgbInt[2]);
log.debug("Color change with XY: " + xy.get(0) + " " + xy.get(1) + " Resulting RGB Values: " + rgb.get(0) + " " + rgb.get(1)
log.debug("Color change with XY: " + xy.get(0) + " " + xy.get(1) + " " + brightness + " Resulting RGB Values: " + rgb.get(0) + " " + rgb.get(1)
+ " " + rgb.get(2));
return rgb;
}
@@ -179,10 +283,10 @@ public class ColorDecode {
private static double assureBounds(double value) {
if (value < 0.0) {
value = 0;
value = 0.0;
}
if (value > 255.0) {
value = 255;
value = 255.0;
}
return value;
}
@@ -252,8 +356,9 @@ public class ColorDecode {
List<Double> xyData = (List<Double>) colorData.getData();
request = request.replace(COLOR_XY, String.format("%f,%f", xyData.get(0), xyData.get(1)));
} else {
List<Double> xyData = (List<Double>) colorData.getData();
request = request.replace(COLOR_XY, String.format("%f,%f", xyData.get(0), xyData.get(1)));
float[] xyz = ColorConverter.RGBtoXYZ(rgb.get(0), rgb.get(1), rgb.get(2));
XYColorSpace theXYcolor = ColorConverter.XYZtoXY(xyz[0], xyz[1], xyz[2]);
request = request.replace(COLOR_XY, String.format("%f,%f",theXYcolor.getXy()[0], theXYcolor.getXy()[1]));
}
notDone = true;
}
@@ -263,9 +368,9 @@ public class ColorDecode {
HueSatBri hslData = (HueSatBri) colorData.getData();
request = request.replace(COLOR_H, String.format("%d", hslData.getHue()));
} else {
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[] hsb;
hsb = ColorConverter.RGBtoHSL(rgb.get(0), rgb.get(1), rgb.get(2));
float hue = hsb[0];
request = request.replace(COLOR_H, String.format("%f", hue));
}
notDone = true;
@@ -276,8 +381,8 @@ public class ColorDecode {
HueSatBri hslData = (HueSatBri) colorData.getData();
request = request.replace(COLOR_S, String.format("%d", hslData.getSat()));
} else {
float[] hsb = new float[3];
Color.RGBtoHSB(rgb.get(0), rgb.get(1), rgb.get(2), hsb);
float[] hsb;
hsb = ColorConverter.RGBtoHSL(rgb.get(0), rgb.get(1), rgb.get(2));
float sat = hsb[1] * (float) 100.0;
request = request.replace(COLOR_S, String.format("%f", sat));
}
@@ -289,7 +394,7 @@ public class ColorDecode {
HueSatBri hslData = (HueSatBri) colorData.getData();
request = request.replace(COLOR_BRI, String.format("%d", hslData.getBri()));
} else {
request = request.replace(COLOR_BRI, String.format("%f", setIntensity));
request = request.replace(COLOR_BRI, String.format("%d", setIntensity));
}
notDone = true;
}
@@ -301,8 +406,8 @@ public class ColorDecode {
String.format("%d,%d,%d", hslData.getHue(), hslData.getSat(), hslData.getBri()));
} else {
float[] hsb = new float[3];
Color.RGBtoHSB(rgb.get(0), rgb.get(1), rgb.get(2), hsb);
float hue = hsb[0] * (float) 360.0;
hsb = ColorConverter.RGBtoHSL(rgb.get(0), rgb.get(1), rgb.get(2));
float hue = hsb[0];
float sat = hsb[1] * (float) 100.0;
float bright = hsb[2] * (float) 100.0;
request = request.replace(COLOR_HSB, String.format("%f,%f,%f", hue, sat, bright));

View File

@@ -1221,12 +1221,44 @@ public class HueMulator {
isOnRequest = true;
}
if(device.isOnFirstDim()) {
if(isDimRequest && !device.getDeviceState().isOn()) {
isOnRequest = true;
theStateChanges.setOn(true);
// isDimRequest = false;
// isColorRequest = false;
} else if (isDimRequest && device.getDeviceState().isOn()) {
if (device.getDeviceState().getBri() == theStateChanges.getBri()) {
isOnRequest = true;
theStateChanges.setOn(true);
// isDimRequest = false;
// isColorRequest = false;
} else {
isOnRequest = false;
// isDimRequest = true;
// isColorRequest = false;
}
}
} else if (device.isOnWhenDimPresent()) {
if (isDimRequest) {
isOnRequest = true;
theStateChanges.setOn(true);
}
} else if (device.isDimNoOn()) {
if (isDimRequest && isOnRequest) {
isOnRequest = false;
}
}
if(isColorRequest && isDimRequest && !device.isDimOnColor()) {
isDimRequest = false;
}
/* Old code supperceded by the above block
if (!device.isOnFirstDim() && device.isOnWhenDimPresent() && isDimRequest && !isOnRequest) {
isOnRequest = true;
theStateChanges.setOn(true);
} else if (!device.isOnFirstDim() && !device.isOnWhenDimPresent() && isDimRequest) {
// isOnRequest = false;
}
} else
if (device.isOnFirstDim() && isDimRequest && !device.getDeviceState().isOn()) {
isOnRequest = true;
@@ -1245,6 +1277,7 @@ public class HueMulator {
isColorRequest = false;
}
}
*/
if (isOnRequest) {
if (bridgeSettings.isTracestate())

View File

@@ -139,8 +139,7 @@ public class HassHome implements Home {
hassCommand = aGsonHandler.fromJson(anItem.getItem(), HassCommand.class);
else
hassCommand = aGsonHandler.fromJson(anItem.getItem().getAsString().replaceAll("^\"|\"$", ""), HassCommand.class);
hassCommand.setBri(BrightnessDecode.replaceIntensityValue(hassCommand.getBri(),
BrightnessDecode.calculateIntensity(intensity, targetBri, targetBriInc), false));
hassCommand.setBri(BrightnessDecode.calculateReplaceIntensityValue(hassCommand.getBri(), intensity, targetBri, targetBriInc, false));
HomeAssistant homeAssistant = getHomeAssistant(hassCommand.getHassName());
if (homeAssistant == null) {
log.warn("Should not get here, no HomeAssistants available");

View File

@@ -479,7 +479,7 @@ app.service('bridgeService', function ($rootScope, $http, $base64, $location, ng
this.pushLinkButton = function () {
return $http.put(this.state.systemsbase + "/presslinkbutton").then(
function (response) {
self.displayTimer("Link your device", 30000);
self.displayTimer("Link your device", self.state.settings.linkbuttontimeout * 1000);
},
function (error) {
if (error.status === 401)
@@ -1547,26 +1547,42 @@ app.service('bridgeService', function ($rootScope, $http, $base64, $location, ng
};
this.toXY = function (red, green, blue) {
//Gamma corrective
red = (red > 0.04045) ? Math.pow((red + 0.055) / (1.0 + 0.055), 2.4) : (red / 12.92);
green = (green > 0.04045) ? Math.pow((green + 0.055) / (1.0 + 0.055), 2.4) : (green / 12.92);
blue = (blue > 0.04045) ? Math.pow((blue + 0.055) / (1.0 + 0.055), 2.4) : (blue / 12.92);
var r = red / 255;
var g = green / 255;
var b = blue / 255;
//R
if ( r > 0.04045)
r = Math.pow(( ( r + 0.055 ) / 1.055 ), 2.4);
else
r /= 12.92;
//G
if ( g > 0.04045)
g = Math.pow(( ( g + 0.055 ) / 1.055 ), 2.4);
else
g /= 12.92;
//B
if ( b > 0.04045)
b = Math.pow(( ( b + 0.055 ) / 1.055 ), 2.4);
else
b /= 12.92;
r *= 100;
g *= 100;
b *= 100;
var x = 0.412453 * r + 0.35758 * g + 0.180423 * b;
var y = 0.212671 * r + 0.71516 * g + 0.072169 * b;
var z = 0.019334 * r + 0.119193 * g + 0.950227 * b;
var newX = x / (x + y + z);
var newY = y / (x + y + z);
var interBright = (y / 100) * 254;
var newBright = Math.round(interBright);
//Apply wide gamut conversion D65
var X = red * 0.664511 + green * 0.154324 + blue * 0.162028;
var Y = red * 0.283881 + green * 0.668433 + blue * 0.047685;
var Z = red * 0.000088 + green * 0.072310 + blue * 0.986039;
var fx = X / (X + Y + Z);
var fy = Y / (X + Y + Z);
if (isNaN(fx)) {
fx = 0.0;
}
if (isNaN(fy)) {
fy = 0.0;
}
return [fx.toPrecision(4), fy.toPrecision(4)];
return [newX.toPrecision(6), newY.toPrecision(6), newBright];
};
this.testUrl = function (device, type, value, valueType) {
@@ -1592,7 +1608,7 @@ app.service('bridgeService', function ($rootScope, $http, $base64, $location, ng
if (valueType === "color" && value) {
if (addComma)
testBody = testBody + ",";
testBody = testBody + "\"xy\": [" + value[0] + "," + value[1] + "]";
testBody = testBody + "\"xy\": [" + value[0] + "," + value[1] + "],\"bri\":" + value[2];
}
testBody = testBody + "}";
if (testBody === "{}") {

View File

@@ -114,6 +114,18 @@
ng-model="device.onFirstDim" ng-true-value=true
ng-false-value=false> {{device.onFirstDim}}</td>
</tr>
<tr>
<td><label>Dim only when On present (If dim is present and the on request is present, the on request will not be sent. This is overriden by the above settings.)</label></td>
<td><input type="checkbox"
ng-model="device.dimNoOn" ng-true-value=true
ng-false-value=false> {{device.dimNoOn}}</td>
</tr>
<tr>
<td><label>Send dim when color request present and dim present</label></td>
<td><input type="checkbox"
ng-model="device.dimOnColor" ng-true-value=true
ng-false-value=false> {{device.dimOnColor}}</td>
</tr>
<tr>
<td><label>Filter Address (comma separated list)</label></td>
<td><input type="text" class="form-control" id="device-requester-addr"

View File

@@ -844,6 +844,11 @@
<td><input id="bridge-settings-upnpsenddelay" class="form-control" type="number"
ng-model="bridge.settings.upnpsenddelay" min="100" max="15000"></td>
</tr>
<tr>
<td>Link Button Timeout (seconds)</td>
<td><input id="bridge-settings-linkbuttontimeout" class="form-control" type="number"
ng-model="bridge.settings.linkbuttontimeout" min="30"></td>
</tr>
<tr>
<td>ID Seed (start numbering from this value)</td>
<td><input id="bridge-settings-seedid" class="form-control" type="number"

View File

@@ -1,5 +1,6 @@
package com.bwssystems.color.test;
import java.awt.Color;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -17,10 +18,10 @@ public class ConvertCIEColorTestCase {
@Test
public void testColorConverterXYtoRGB() {
ArrayList<Double> xy = new ArrayList<Double>(Arrays.asList(Double.parseDouble("0.671254"), Double.parseDouble("0.303273")));
ArrayList<Double> xy = new ArrayList<Double>(Arrays.asList(Double.parseDouble("0.20821628789344535"), Double.parseDouble("0.22503526273269103")));
XYColorSpace xyColor = new XYColorSpace();
xyColor.setBrightness(50);
xyColor.setBrightness(56);
float[] xyFloat = new float[2];
xyFloat[0] = xy.get(0).floatValue();
xyFloat[1] = xy.get(1).floatValue();
@@ -32,12 +33,29 @@ public class ConvertCIEColorTestCase {
rgbDecode.add(1, rgb[1]);
rgbDecode.add(2, rgb[2]);
List<Integer> assertDecode = new ArrayList<Integer>();
assertDecode.add(0, 255);
assertDecode.add(1, 0);
assertDecode.add(2, 5);
assertDecode.add(0, 60);
assertDecode.add(1, 134);
assertDecode.add(2, 196);
Assert.assertEquals(rgbDecode, assertDecode);
}
@Test
public void testColorConverterRGBtoXY() {
int red = 60;
int green = 134;
int blue = 196;
float[] xyz = ColorConverter.RGBtoXYZ(red, green, blue);
XYColorSpace theColorSpace = ColorConverter.XYZtoXY(xyz[0], xyz[1], xyz[2]);
List<Float> xyDecode = new ArrayList<Float>();
xyDecode.add(0, theColorSpace.getXy()[0]);
xyDecode.add(1, theColorSpace.getXy()[1]);
List<Float> assertDecode = new ArrayList<Float>();
assertDecode.add(0, 0.20821705f);
assertDecode.add(1, 0.22506176f);
Assert.assertEquals(xyDecode, assertDecode);
}
@Test
public void testColorConversionXYtoRGB1() {
ArrayList<Double> xy = new ArrayList<Double>(Arrays.asList(Double.parseDouble("0.671254"), Double.parseDouble("0.303273")));
@@ -70,6 +88,22 @@ public class ConvertCIEColorTestCase {
Assert.assertEquals(rgbIntVal, 15270119);
}
@Test
public void testColorConversionXYtoRGB3() {
ArrayList<Double> xy = new ArrayList<Double>(Arrays.asList(Double.parseDouble("0.20821628789344535"), Double.parseDouble("0.22503526273269103")));
List<Integer> colorDecode = ColorDecode.convertCIEtoRGB(xy, 56);
List<Integer> assertDecode = new ArrayList<Integer>();
assertDecode.add(0, 60);
assertDecode.add(1, 134);
assertDecode.add(2, 196);
Assert.assertEquals(colorDecode, assertDecode);
// ColorData colorData = new ColorData(ColorData.ColorMode.XY, xy);
// int rgbIntVal = ColorDecode.getIntRGB(colorData, 56);
// Assert.assertEquals(rgbIntVal, 15270119);
}
@Test
public void testColorConversionHSBtoRGB1() {
HueSatBri hsb = new HueSatBri();
@@ -79,12 +113,30 @@ public class ConvertCIEColorTestCase {
List<Integer> colorDecode = ColorDecode.convertHSBtoRGB(hsb);
List<Integer> assertDecode = new ArrayList<Integer>();
assertDecode.add(0, 60);
assertDecode.add(1, 97);
assertDecode.add(2, 128);
assertDecode.add(0, 61);
assertDecode.add(1, 134);
assertDecode.add(2, 196);
Assert.assertEquals(colorDecode, assertDecode);
}
@Test
public void testColorConverterRGBtoHSB() {
int red = 61;
int green = 134;
int blue = 196;
float[] hsl = ColorConverter.RGBtoHSL(red, green, blue);
List<Integer> hsbDecode = new ArrayList<Integer>();
hsbDecode.add(0, (int) (hsl[0] / 360f * 65535f));
hsbDecode.add(1, (int) (hsl[1] * 254f));
hsbDecode.add(2, (int) (hsl[2] * 254f));
List<Integer> assertDecode = new ArrayList<Integer>();
assertDecode.add(0, 37783);
assertDecode.add(1, 135);
assertDecode.add(2, 127);
Assert.assertEquals(hsbDecode, assertDecode);
}
@Test
public void testColorConversionCTtoRGB() {
Integer ct = 500;