Compare commits

...

5 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
bwssystems
969ed352f7 Update handling of upnp and updated how unique ids are generated 2020-12-01 19:32:42 -06:00
bwssystems
c98513c365 remove .project file 2020-11-19 12:16:08 -06:00
bwssystems
add9617a07 Fix command line config path issue
When the command line config path is used and the ocnfig file has no entry for configfile a null pointer exception occurrs
2020-11-19 12:09:13 -06:00
22 changed files with 622 additions and 290 deletions

1
.gitignore vendored
View File

@@ -24,3 +24,4 @@ sftp-config\.json
/node_modules /node_modules
package-lock.json package-lock.json
.project

View File

@@ -1,23 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>ha-bridge</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
</natures>
</projectDescription>

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. ATTENTION: Due to port 80 being the default, Linux restricts this to super user. Use the instructions below.
``` ```
java -jar ha-bridge-5.3.1RC2.jar java -jar ha-bridge-5.3.1RC5.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.3.1RC2.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:~ $ 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.3.1RC2/ha-bridge-5.3.1RC2.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: Create the ha-bridge.service unit file:
@@ -89,7 +89,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.3.1RC2.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] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target

View File

@@ -5,7 +5,7 @@
<groupId>com.bwssystems.HABridge</groupId> <groupId>com.bwssystems.HABridge</groupId>
<artifactId>ha-bridge</artifactId> <artifactId>ha-bridge</artifactId>
<version>5.3.1RC1</version> <version>5.3.1RC5-java11</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>HA Bridge</name> <name>HA Bridge</name>
@@ -172,7 +172,7 @@
<configuration> <configuration>
<rules> <rules>
<requireMavenVersion> <requireMavenVersion>
<!-- Change this to Version 3.3 for Java 1.8 and Raspberry PI compilation --> <!-- Change this to Version 3.3 for Java 1.8 and Raspberry PI compilation, Java 11 is 3.6 -->
<version>3.6</version> <version>3.6</version>
</requireMavenVersion> </requireMavenVersion>
</rules> </rules>
@@ -184,7 +184,7 @@
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version> <version>3.8.1</version>
<configuration> <configuration>
<!-- Comment this release line out for Java 1.8 and Raspberry PI compilation --> <!-- Comment this release line out for Java 1.8 and Raspberry PI compilation -->
<release>11</release> <release>11</release>
<!-- Uncomment the next two lines for Java 1.8 and Raspberry PI compilation --> <!-- Uncomment the next two lines for Java 1.8 and Raspberry PI compilation -->
<!-- <source>1.8</source> --> <!-- <source>1.8</source> -->

View File

@@ -200,7 +200,10 @@ public class BridgeSettings extends BackupHandler {
theBridgeSettings.setNumberoflogmessages(Integer.valueOf(Configuration.NUMBER_OF_LOG_MESSAGES)); theBridgeSettings.setNumberoflogmessages(Integer.valueOf(Configuration.NUMBER_OF_LOG_MESSAGES));
if(theBridgeSettings.getButtonsleep() == null || theBridgeSettings.getButtonsleep() < 0) 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.setVeraconfigured(theBridgeSettings.isValidVera());
theBridgeSettings.setFibaroconfigured(theBridgeSettings.isValidFibaro()); theBridgeSettings.setFibaroconfigured(theBridgeSettings.isValidFibaro());
@@ -250,10 +253,10 @@ public class BridgeSettings extends BackupHandler {
return; return;
try { try {
theBridgeSettings = new Gson().fromJson(jsonContent, BridgeSettingsDescriptor.class); theBridgeSettings = new Gson().fromJson(jsonContent, BridgeSettingsDescriptor.class);
} catch (Exception e) {
log.warn("Issue loading values from file: " + aPath.toUri().toString() + ", Gson convert failed.");
theBridgeSettings = new BridgeSettingsDescriptor();
theBridgeSettings.setConfigfile(aPath.toString()); theBridgeSettings.setConfigfile(aPath.toString());
} catch (Exception e) {
log.warn("Issue loading values from file: " + aPath.toUri().toString() + ", Gson convert failed. Using default settings.");
theBridgeSettings = new BridgeSettingsDescriptor();
} }
} }

View File

@@ -132,6 +132,13 @@ public class BridgeSettingsDescriptor {
@SerializedName("haaddressessecured") @SerializedName("haaddressessecured")
@Expose @Expose
private boolean haaddressessecured; private boolean haaddressessecured;
@SerializedName("upnpadvanced")
@Expose
private boolean upnpadvanced;
@SerializedName("linkbuttontimeout")
@Expose
private Integer linkbuttontimeout;
// @SerializedName("activeloggers") // @SerializedName("activeloggers")
// @Expose // @Expose
// private List<NameValue> activeloggers; // private List<NameValue> activeloggers;
@@ -192,6 +199,9 @@ public class BridgeSettingsDescriptor {
this.upnporiginal = false; this.upnporiginal = false;
this.seedid = 100; this.seedid = 100;
this.haaddressessecured = false; this.haaddressessecured = false;
this.configfile = Configuration.CONFIG_FILE;
this.upnpadvanced = false;
this.linkbuttontimeout = Configuration.LINK_BUTTON_TIMEOUT;
} }
public String getUpnpConfigAddress() { public String getUpnpConfigAddress() {
@@ -847,4 +857,20 @@ public class BridgeSettingsDescriptor {
public void setHaaddressessecured(boolean haaddressessecured) { public void setHaaddressessecured(boolean haaddressessecured) {
this.haaddressessecured = haaddressessecured; this.haaddressessecured = haaddressessecured;
} }
public boolean isUpnpadvanced() {
return upnpadvanced;
}
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 UPNP_SEND_DELAY = 650;
public static final int BROADLINK_DISCOVER_PORT = 40000; public static final int BROADLINK_DISCOVER_PORT = 40000;
public static final int BROADLINK_DISCONVER_TIMEOUT = 5000; 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()) { if(!request.body().isEmpty()) {
linkParams = new Gson().fromJson(request.body(), LinkParams.class); linkParams = new Gson().fromJson(request.body(), LinkParams.class);
if(linkParams.getSeconds() <= 0) if(linkParams.getSeconds() <= 0)
linkParams.setSeconds(1); linkParams.setSeconds(3);
} }
else { else {
linkParams = new LinkParams(); linkParams = new LinkParams();
linkParams.setSilent(false); linkParams.setSilent(false);
linkParams.setSeconds(30); linkParams.setSeconds(bridgeSettings.getBridgeSettingsDescriptor().getLinkbuttontimeout());
} }
if(!linkParams.isSilent()) if(!linkParams.isSilent())
log.info("Link button pressed...."); log.info("Link button pressed....");

View File

@@ -2,7 +2,7 @@ package com.bwssystems.HABridge.api.hue;
public class HueConstants { public class HueConstants {
public final static String HUB_VERSION = "9999999999"; public final static String HUB_VERSION = "9999999999";
public final static String API_VERSION = "1.19.0"; public final static String API_VERSION = "1.17.0";
public final static String MODEL_ID = "BSB002"; public final static String MODEL_ID = "BSB002";
public final static String UUID_PREFIX = "2f402f80-da50-11e1-9b23-"; public final static String UUID_PREFIX = "2f402f80-da50-11e1-9b23-";
} }

View File

@@ -92,6 +92,12 @@ public class DeviceDescriptor{
@SerializedName("startupActions") @SerializedName("startupActions")
@Expose @Expose
private String startupActions; private String startupActions;
@SerializedName("dimNoOn")
@Expose
private boolean dimNoOn;
@SerializedName("dimOnColor")
@Expose
private boolean dimOnColor;
public String getName() { public String getName() {
return name; return name;
@@ -355,4 +361,20 @@ public class DeviceDescriptor{
public void setStartupActions(String startupActions) { public void setStartupActions(String startupActions) {
this.startupActions = 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

@@ -30,6 +30,8 @@ import com.google.gson.JsonSyntaxException;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Arrays; import java.util.Arrays;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/* /*
* This is an in memory list to manage the configured devices and saves the list as a JSON string to a file for later * This is an in memory list to manage the configured devices and saves the list as a JSON string to a file for later
@@ -188,7 +190,7 @@ public class DeviceRepository extends BackupHandler {
nextId++; nextId++;
} }
if (descriptors[i].getUniqueid() == null || descriptors[i].getUniqueid().length() == 0) { if (descriptors[i].getUniqueid() == null || descriptors[i].getUniqueid().length() == 0) {
descriptors[i].setUniqueid("00:11:22:33:44:55:66:" + hueUniqueId(Integer.valueOf(descriptors[i].getId()))); descriptors[i].setUniqueid(hueUniqueId(Integer.valueOf(descriptors[i].getId())));
} }
put(descriptors[i].getId(), descriptors[i]); put(descriptors[i].getId(), descriptors[i]);
theNames = theNames + " " + descriptors[i].getName() + ", "; theNames = theNames + " " + descriptors[i].getName() + ", ";
@@ -206,11 +208,10 @@ public class DeviceRepository extends BackupHandler {
DeviceDescriptor theDevice; DeviceDescriptor theDevice;
boolean findNext = true; boolean findNext = true;
nextId = seedId; nextId = seedId;
while(deviceIterator.hasNext()) { while (deviceIterator.hasNext()) {
theDevice = deviceIterator.next(); theDevice = deviceIterator.next();
if(theDevice.isLockDeviceId()) { if (theDevice.isLockDeviceId()) {
lockedIds.add(theDevice.getId()); lockedIds.add(theDevice.getId());
} }
} }
@@ -220,15 +221,15 @@ public class DeviceRepository extends BackupHandler {
theDevice = deviceIterator.next(); theDevice = deviceIterator.next();
if (!theDevice.isLockDeviceId()) { if (!theDevice.isLockDeviceId()) {
findNext = true; findNext = true;
while(findNext) { while (findNext) {
if(lockedIds.contains(String.valueOf(nextId))) { if (lockedIds.contains(String.valueOf(nextId))) {
nextId++; nextId++;
} else { } else {
findNext = false; findNext = false;
} }
} }
theDevice.setId(String.valueOf(nextId)); theDevice.setId(String.valueOf(nextId));
theDevice.setUniqueid("00:11:22:33:44:55:66:" + hueUniqueId(nextId)); theDevice.setUniqueid(hueUniqueId(nextId));
nextId++; nextId++;
} }
newdevices.put(theDevice.getId(), theDevice); newdevices.put(theDevice.getId(), theDevice);
@@ -297,27 +298,51 @@ public class DeviceRepository extends BackupHandler {
} }
private String hueUniqueId(Integer anId) { private String hueUniqueId(Integer anId) {
String theUniqueId; String theUniqueId = null;
Integer newValue; Integer newValue;
String hexValueLeft; String hexValueLeft;
String hexValueRight; String hexValueRight;
newValue = anId % 256; MessageDigest md = null;
if (newValue <= 0)
newValue = 1;
else if (newValue > 255)
newValue = 255;
hexValueLeft = HexLibrary.byteToHex(newValue.byteValue());
newValue = anId / 256;
newValue = newValue % 256;
if (newValue < 0)
newValue = 0;
else if (newValue > 255)
newValue = 255;
hexValueRight = HexLibrary.byteToHex(newValue.byteValue());
theUniqueId = String.format("%s-%s", hexValueLeft, hexValueRight).toUpperCase(); try {
md = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
log.warn("Cannot get MD5 utility to hash unique ids.");
}
if(md != null) {
md.update(anId.toString().getBytes());
byte[] digest = md.digest();
theUniqueId = String.format("%s:%s:%s:%s:%s:%s:%s-%s",
HexLibrary.encodeHexString(digest).substring(0, 2),
HexLibrary.encodeHexString(digest).substring(2, 4),
HexLibrary.encodeHexString(digest).substring(4, 6),
HexLibrary.encodeHexString(digest).substring(6, 8),
HexLibrary.encodeHexString(digest).substring(8, 10),
HexLibrary.encodeHexString(digest).substring(10, 12),
HexLibrary.encodeHexString(digest).substring(12, 14),
HexLibrary.encodeHexString(digest).substring(14, 16));
}
if(theUniqueId == null) {
newValue = anId % 256;
if (newValue <= 0)
newValue = 1;
else if (newValue > 255)
newValue = 255;
hexValueLeft = HexLibrary.byteToHex(newValue.byteValue());
newValue = anId / 256;
newValue = newValue % 256;
if (newValue < 0)
newValue = 0;
else if (newValue > 255)
newValue = 255;
hexValueRight = HexLibrary.byteToHex(newValue.byteValue());
theUniqueId = String.format("11:22:33:44:55:66:%s-%s", hexValueLeft, hexValueRight).toUpperCase();
}
return theUniqueId; return theUniqueId;
} }
} }

View File

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

View File

@@ -18,6 +18,8 @@ package com.bwssystems.HABridge.hue;
* XYZ -> CIE-LAB -> XYZ * XYZ -> CIE-LAB -> XYZ
* @author Diego Catalano * @author Diego Catalano
*/ */
public class ColorConverter { public class ColorConverter {
/** /**
@@ -26,6 +28,7 @@ public class ColorConverter {
private ColorConverter() {} private ColorConverter() {}
public static enum YCbCrColorSpace {ITU_BT_601,ITU_BT_709_HDTV}; 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 // XYZ (Tristimulus) Reference values of a perfect reflecting diffuser
@@ -259,7 +262,7 @@ public class ColorConverter {
* @param blue Blue coefficient. * @param blue Blue coefficient.
* @return Normalized RGChromaticity. Range[0..1]. * @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[] color = new double[5];
double sum = red + green + blue; double sum = red + green + blue;
@@ -276,24 +279,7 @@ public class ColorConverter {
double rS = color[0] - 0.333; double rS = color[0] - 0.333;
double gS = color[1] - 0.333; double gS = color[1] - 0.333;
//saturation //saturationBRGBtoHSV(int red, int green, int blue){
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){
float[] hsv = new float[3]; float[] hsv = new float[3];
float r = red / 255f; float r = red / 255f;
float g = green / 255f; float g = green / 255f;
@@ -633,66 +619,66 @@ public class ColorConverter {
} }
/** /**
* RGB -> HLS. * RGB -> HSL.
* @param red Red coefficient. Values in the range [0..255]. * @param red Red coefficient. Values in the range [0..255].
* @param green Green 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]. * @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[] hsl = new float[3];
float r = red / 255f; double r = red;
float g = green / 255f; double g = green;
float b = blue / 255f; double b = blue;
float max = Math.max(r,Math.max(r,b)); double max = Math.max(r,Math.max(g,b));
float min = Math.min(r,Math.min(r,b)); double min = Math.min(r,Math.min(g,b));
float delta = max - min; // double delta = max - min;
//HSK //HSK
float h = 0; Double h = 0d;
float s = 0; Double s = 0d;
float l = (max + min) / 2; Double l = 0d;
if ( delta == 0 ){ //saturation
// gray color double cnt = (max + min) / 2d;
h = 0; if (cnt <= 127d) {
s = 0.0f; s = ((max - min) / (max + min));
}
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;
} }
else if ( g == max ) else {
{ s = ((max - min) / (510d - max - min));
hue = ( 1.0f / 3 ) + ( ( b - r ) / 6 ) / delta;
}
else
{
hue = ( 2.0f / 3 ) + ( ( r - g ) / 6 ) / delta;
} }
// correct hue if needed //lightness
if ( hue < 0 ) l = ((max + min) / 2d) / 255d;
hue += 1;
if ( hue > 1 )
hue -= 1;
h = (int) ( hue * 360 ); //hue
} if (Math.abs(max - min) <= EPSILON) {
h = 0d;
s = 0d;
}
else {
double diff = max - min;
hsl[0] = h; if (Math.abs(max - r) <= EPSILON) {
hsl[1] = s; h = 60d * (g - b) / diff;
hsl[2] = l; }
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.floatValue();
hsl[1] = s.floatValue();
hsl[2] = l.floatValue();
return hsl; return hsl;
} }
@@ -931,10 +917,15 @@ public class ColorConverter {
*/ */
public static float[] XYtoXYZ(XYColorSpace xy){ public static float[] XYtoXYZ(XYColorSpace xy){
float[] xyz = new float[3]; float[] xyz = new float[3];
/* Old Way
xyz[0] = (xy.getBrightnessAdjusted() / xy.getXy()[1]) * xy.getXy()[0]; xyz[0] = (xy.getBrightnessAdjusted() / xy.getXy()[1]) * xy.getXy()[0];
xyz[1] = xy.getBrightnessAdjusted(); xyz[1] = xy.getBrightnessAdjusted();
xyz[2] = (xy.getBrightnessAdjusted() / xy.getXy()[1]) * (1.0f - xy.getXy()[0] - xy.getXy()[1]); 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; return xyz;
} }

View File

@@ -4,12 +4,12 @@ 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;
import com.bwssystems.HABridge.hue.ColorData; // import com.bwssystems.HABridge.hue.ColorData;
public class ColorDecode { public class ColorDecode {
private static final Logger log = LoggerFactory.getLogger(ColorDecode.class); private static final Logger log = LoggerFactory.getLogger(ColorDecode.class);
@@ -27,73 +27,81 @@ public class ColorDecode {
private static final String COLOR_BRI = "${colorbri}"; private static final String COLOR_BRI = "${colorbri}";
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> 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; List<Integer> rgb;
Float hue = (Float)(hsb.getHue()*1.0f); Float hue = (Float)(hsb.getHue()*1.0f);
Float saturation = (Float)(hsb.getSat()*1.0f); Float saturation = (Float)(hsb.getSat()*1.0f);
Float brightness = (Float)(hsb.getBri()*1.0f); Float brightness = (Float)(hsb.getBri()*1.0f);
log.info("Hue = " + hue + ", Sat = " + saturation + ", Bri = " + brightness); log.info("Hue = " + hue + ", Sat = " + saturation + ", Bri = " + brightness);
//Convert Hue into degrees for HSB //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) //Bri and Sat must be values from 0-1 (~percentage)
brightness = brightness / 255.0f; // ightness = brightness / 255.0f;
saturation = saturation / 255.0f; // saturation = saturation / 255.0f;
brightness = brightness / 254.0f;
saturation = saturation / 254.0f;
Float r = 0f; Float r = 0f;
Float g = 0f; Float g = 0f;
Float b = 0f; Float b = 0f;
if (saturation == 0) if(brightness > 0.0f) {
{ if (saturation == 0)
r = g = b = brightness; {
} r = g = b = brightness;
else }
{ else
// the color wheel consists of 6 sectors. {
Float sectorPos = hue / 60.0f; // the color wheel consists of 6 sectors.
int sectorNumber = (int)(Math.floor(sectorPos)); Float sectorPos = hue / 60.0f;
// get the fractional part of the sector int sectorNumber = (int)(Math.floor(sectorPos));
Float fractionalSector = sectorPos - sectorNumber; // get the fractional part of the sector
Float fractionalSector = sectorPos - sectorNumber;
// calculate values for the three axes of the color. // calculate values for the three axes of the color.
Float p = brightness * (1.0f - saturation); Float p = brightness * (1.0f - saturation);
Float q = brightness * (1.0f - (saturation * fractionalSector)); Float q = brightness * (1.0f - (saturation * fractionalSector));
Float t = brightness * (1.0f - (saturation * (1f - 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. // assign the fractional colors to r, g, and b based on the sector the angle is in.
switch (sectorNumber) switch (sectorNumber)
{ {
case 0: case 0:
r = brightness; r = brightness;
g = t; g = t;
b = p; b = p;
break; break;
case 1: case 1:
r = q; r = q;
g = brightness; g = brightness;
b = p; b = p;
break; break;
case 2: case 2:
r = p; r = p;
g = brightness; g = brightness;
b = t; b = t;
break; break;
case 3: case 3:
r = p; r = p;
g = q; g = q;
b = brightness; b = brightness;
break; break;
case 4: case 4:
r = t; r = t;
g = p; g = p;
b = brightness; b = brightness;
break; break;
case 5: case 5:
r = brightness; r = brightness;
g = p; g = p;
b = q; b = q;
break; break;
} }
}
} }
//Check if any value is out of byte range //Check if any value is out of byte range
@@ -114,10 +122,106 @@ public class ColorDecode {
rgb.add((int)Math.round(r*255)); rgb.add((int)Math.round(r*255));
rgb.add((int)Math.round(g*255)); rgb.add((int)Math.round(g*255));
rgb.add((int)Math.round(b*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)); + 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; 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) { public static List<Integer> convertCIEtoRGB(List<Double> xy, int brightness) {
List<Integer> rgb; List<Integer> rgb;
@@ -133,7 +237,7 @@ public class ColorDecode {
rgb.add(rgbInt[0]); rgb.add(rgbInt[0]);
rgb.add(rgbInt[1]); rgb.add(rgbInt[1]);
rgb.add(rgbInt[2]); 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)); + " " + rgb.get(2));
return rgb; return rgb;
} }
@@ -179,10 +283,10 @@ public class ColorDecode {
private static double assureBounds(double value) { private static double assureBounds(double value) {
if (value < 0.0) { if (value < 0.0) {
value = 0; value = 0.0;
} }
if (value > 255.0) { if (value > 255.0) {
value = 255; value = 255.0;
} }
return value; return value;
} }
@@ -252,8 +356,9 @@ public class ColorDecode {
List<Double> xyData = (List<Double>) colorData.getData(); List<Double> xyData = (List<Double>) colorData.getData();
request = request.replace(COLOR_XY, String.format("%f,%f", xyData.get(0), xyData.get(1))); request = request.replace(COLOR_XY, String.format("%f,%f", xyData.get(0), xyData.get(1)));
} else { } else {
List<Double> xyData = (List<Double>) colorData.getData(); float[] xyz = ColorConverter.RGBtoXYZ(rgb.get(0), rgb.get(1), rgb.get(2));
request = request.replace(COLOR_XY, String.format("%f,%f", xyData.get(0), xyData.get(1))); 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; notDone = true;
} }
@@ -263,9 +368,9 @@ public class ColorDecode {
HueSatBri hslData = (HueSatBri) colorData.getData(); HueSatBri hslData = (HueSatBri) colorData.getData();
request = request.replace(COLOR_H, String.format("%d", hslData.getHue())); request = request.replace(COLOR_H, String.format("%d", hslData.getHue()));
} else { } else {
float[] hsb = new float[3]; float[] hsb;
Color.RGBtoHSB(rgb.get(0), rgb.get(1), rgb.get(2), hsb); hsb = ColorConverter.RGBtoHSL(rgb.get(0), rgb.get(1), rgb.get(2));
float hue = hsb[0] * (float) 360.0; float hue = hsb[0];
request = request.replace(COLOR_H, String.format("%f", hue)); request = request.replace(COLOR_H, String.format("%f", hue));
} }
notDone = true; notDone = true;
@@ -276,8 +381,8 @@ public class ColorDecode {
HueSatBri hslData = (HueSatBri) colorData.getData(); HueSatBri hslData = (HueSatBri) colorData.getData();
request = request.replace(COLOR_S, String.format("%d", hslData.getSat())); request = request.replace(COLOR_S, String.format("%d", hslData.getSat()));
} else { } else {
float[] hsb = new float[3]; float[] hsb;
Color.RGBtoHSB(rgb.get(0), rgb.get(1), rgb.get(2), hsb); hsb = ColorConverter.RGBtoHSL(rgb.get(0), rgb.get(1), rgb.get(2));
float sat = hsb[1] * (float) 100.0; float sat = hsb[1] * (float) 100.0;
request = request.replace(COLOR_S, String.format("%f", sat)); request = request.replace(COLOR_S, String.format("%f", sat));
} }
@@ -289,7 +394,7 @@ public class ColorDecode {
HueSatBri hslData = (HueSatBri) colorData.getData(); HueSatBri hslData = (HueSatBri) colorData.getData();
request = request.replace(COLOR_BRI, String.format("%d", hslData.getBri())); request = request.replace(COLOR_BRI, String.format("%d", hslData.getBri()));
} else { } else {
request = request.replace(COLOR_BRI, String.format("%f", setIntensity)); request = request.replace(COLOR_BRI, String.format("%d", setIntensity));
} }
notDone = true; notDone = true;
} }
@@ -301,8 +406,8 @@ public class ColorDecode {
String.format("%d,%d,%d", hslData.getHue(), hslData.getSat(), hslData.getBri())); String.format("%d,%d,%d", hslData.getHue(), hslData.getSat(), hslData.getBri()));
} else { } else {
float[] hsb = new float[3]; float[] hsb = new float[3];
Color.RGBtoHSB(rgb.get(0), rgb.get(1), rgb.get(2), hsb); hsb = ColorConverter.RGBtoHSL(rgb.get(0), rgb.get(1), rgb.get(2));
float hue = hsb[0] * (float) 360.0; float hue = hsb[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_HSB, String.format("%f,%f,%f", hue, sat, bright)); request = request.replace(COLOR_HSB, String.format("%f,%f,%f", hue, sat, bright));

View File

@@ -1221,12 +1221,44 @@ public class HueMulator {
isOnRequest = true; 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) { 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
// isOnRequest = false;
}
if (device.isOnFirstDim() && isDimRequest && !device.getDeviceState().isOn()) { if (device.isOnFirstDim() && isDimRequest && !device.getDeviceState().isOn()) {
isOnRequest = true; isOnRequest = true;
@@ -1245,6 +1277,7 @@ public class HueMulator {
isColorRequest = false; isColorRequest = false;
} }
} }
*/
if (isOnRequest) { if (isOnRequest) {
if (bridgeSettings.isTracestate()) if (bridgeSettings.isTracestate())

View File

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

View File

@@ -30,6 +30,7 @@ public class UpnpListener {
private String upnpConfigIP; private String upnpConfigIP;
// private boolean strict; // private boolean strict;
private boolean upnpOriginal; private boolean upnpOriginal;
private boolean upnpAdvanced;
private boolean traceupnp; private boolean traceupnp;
private boolean useUpnpIface; private boolean useUpnpIface;
private BridgeControlDescriptor bridgeControl; private BridgeControlDescriptor bridgeControl;
@@ -38,31 +39,37 @@ public class UpnpListener {
private String httpType; private String httpType;
private HuePublicConfig aHueConfig; private HuePublicConfig aHueConfig;
private Integer theUpnpSendDelay; private Integer theUpnpSendDelay;
/* This is the minimum response needed, all others are for the advanced setting */
private String responseTemplate1 = "HTTP/1.1 200 OK\r\n" + "HOST: %s:%s\r\n" + "CACHE-CONTROL: max-age=100\r\n" private String responseTemplate1 = "HTTP/1.1 200 OK\r\n" + "HOST: %s:%s\r\n" + "CACHE-CONTROL: max-age=100\r\n"
+ "EXT:\r\n" + "LOCATION: %s://%s:%s/description.xml\r\n" + "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/" + "EXT:\r\n" + "LOCATION: %s://%s:%s/description.xml\r\n" + "SERVER: FreeRTOS/6.0.5, UPnP/1.0, IpBridge/"
+ HueConstants.API_VERSION + "\r\n" + "hue-bridgeid: %s\r\n" + "ST: upnp:rootdevice\r\n" + "USN: uuid:"
+ HueConstants.UUID_PREFIX + "%s::upnp:rootdevice\r\n\r\n";
private String responseTemplate2 = "HTTP/1.1 200 OK\r\n" + "HOST: %s:%s\r\n" + "CACHE-CONTROL: max-age=100\r\n"
+ "EXT:\r\n" + "LOCATION: %s://%s:%s/description.xml\r\n" + "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/"
+ HueConstants.API_VERSION + "\r\n" + "hue-bridgeid: %s\r\n" + "ST: uuid:" + HueConstants.UUID_PREFIX
+ "%s\r\n" + "USN: uuid:" + HueConstants.UUID_PREFIX + "%s\r\n\r\n";
private String responseTemplate3 = "HTTP/1.1 200 OK\r\n" + "HOST: %s:%s\r\n" + "CACHE-CONTROL: max-age=100\r\n"
+ "EXT:\r\n" + "LOCATION: %s://%s:%s/description.xml\r\n" + "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/"
+ HueConstants.API_VERSION + "\r\n" + "hue-bridgeid: %s\r\n" + "ST: urn:schemas-upnp-org:device:basic:1\r\n" + HueConstants.API_VERSION + "\r\n" + "hue-bridgeid: %s\r\n" + "ST: urn:schemas-upnp-org:device:basic:1\r\n"
+ "USN: uuid:" + HueConstants.UUID_PREFIX + "%s\r\n\r\n"; + "USN: uuid:" + HueConstants.UUID_PREFIX + "%s\r\n\r\n";
/* These next 2 templates are for the advanced upnp option */
private String responseTemplate2 = "HTTP/1.1 200 OK\r\n" + "HOST: %s:%s\r\n" + "CACHE-CONTROL: max-age=100\r\n"
+ "EXT:\r\n" + "LOCATION: %s://%s:%s/description.xml\r\n" + "SERVER: FreeRTOS/6.0.5, UPnP/1.0, IpBridge/"
+ HueConstants.API_VERSION + "\r\n" + "hue-bridgeid: %s\r\n" + "ST: uuid:" + HueConstants.UUID_PREFIX
+ "%s\r\n" + "USN: uuid:" + HueConstants.UUID_PREFIX + "%s\r\n\r\n";
private String responseTemplate3 = "HTTP/1.1 200 OK\r\n" + "HOST: %s:%s\r\n" + "CACHE-CONTROL: max-age=100\r\n"
+ "EXT:\r\n" + "LOCATION: %s://%s:%s/description.xml\r\n" + "SERVER: FreeRTOS/6.0.5, UPnP/1.0, IpBridge/"
+ HueConstants.API_VERSION + "\r\n" + "hue-bridgeid: %s\r\n" + "ST: upnp:rootdevice\r\n" + "USN: uuid:"
+ HueConstants.UUID_PREFIX + "%s::upnp:rootdevice\r\n\r\n";
/* These notify templates are for the advanced upnp option */
private String notifyTemplate1 = "NOTIFY * HTTP/1.1\r\n" + "HOST: %s:%s\r\n" + "CACHE-CONTROL: max-age=100\r\n" private String notifyTemplate1 = "NOTIFY * HTTP/1.1\r\n" + "HOST: %s:%s\r\n" + "CACHE-CONTROL: max-age=100\r\n"
+ "LOCATION: %s://%s:%s/description.xml\r\n" + "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/" + "LOCATION: %s://%s:%s/description.xml\r\n" + "SERVER: FreeRTOS/6.0.5, UPnP/1.0, IpBridge/"
+ HueConstants.API_VERSION + "\r\n" + "NTS: ssdp:alive\r\n" + "hue-bridgeid: %s\r\n" + "NT: uuid:" + HueConstants.API_VERSION + "\r\n" + "NTS: ssdp:alive\r\n" + "hue-bridgeid: %s\r\n" + "NT: uuid:"
+ HueConstants.UUID_PREFIX + "%s\r\n" + "USN: uuid:" + HueConstants.UUID_PREFIX + "%s\r\n\r\n"; + HueConstants.UUID_PREFIX + "%s\r\n" + "USN: uuid:" + HueConstants.UUID_PREFIX + "%s\r\n\r\n";
private String notifyTemplate2 = "NOTIFY * HTTP/1.1\r\n" + "HOST: %s:%s\r\n" + "CACHE-CONTROL: max-age=100\r\n" private String notifyTemplate2 = "NOTIFY * HTTP/1.1\r\n" + "HOST: %s:%s\r\n" + "CACHE-CONTROL: max-age=100\r\n"
+ "LOCATION: %s://%s:%s/description.xml\r\n" + "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/" + "LOCATION: %s://%s:%s/description.xml\r\n" + "SERVER: FreeRTOS/6.0.5, UPnP/1.0, IpBridge/"
+ HueConstants.API_VERSION + "\r\n" + "NTS: ssdp:alive\r\n" + "hue-bridgeid: %s\r\n" + HueConstants.API_VERSION + "\r\n" + "NTS: ssdp:alive\r\n" + "hue-bridgeid: %s\r\n"
+ "NT: upnp:rootdevice\r\n" + "USN: uuid:" + HueConstants.UUID_PREFIX + "%s::upnp:rootdevice\r\n\r\n"; + "NT: upnp:rootdevice\r\n" + "USN: uuid:" + HueConstants.UUID_PREFIX + "%s::upnp:rootdevice\r\n\r\n";
private String notifyTemplate3 = "NOTIFY * HTTP/1.1\r\n" + "HOST: %s:%s\r\n" + "CACHE-CONTROL: max-age=100\r\n" private String notifyTemplate3 = "NOTIFY * HTTP/1.1\r\n" + "HOST: %s:%s\r\n" + "CACHE-CONTROL: max-age=100\r\n"
+ "LOCATION: %s://%s:%s/description.xml\r\n" + "SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/" + "LOCATION: %s://%s:%s/description.xml\r\n" + "SERVER: FreeRTOS/6.0.5, UPnP/1.0, IpBridge/"
+ HueConstants.API_VERSION + "\r\n" + "NTS: ssdp:alive\r\n" + "hue-bridgeid: %s\r\n" + HueConstants.API_VERSION + "\r\n" + "NTS: ssdp:alive\r\n" + "hue-bridgeid: %s\r\n"
+ "NT: urn:schemas-upnp-org:device:basic:1\r\n" + "USN: uuid:" + HueConstants.UUID_PREFIX + "%s\r\n\r\n"; + "NT: urn:schemas-upnp-org:device:basic:1\r\n" + "USN: uuid:" + HueConstants.UUID_PREFIX + "%s\r\n\r\n";
@@ -75,6 +82,7 @@ public class UpnpListener {
upnpConfigIP = theSettings.getBridgeSettingsDescriptor().getUpnpConfigAddress(); upnpConfigIP = theSettings.getBridgeSettingsDescriptor().getUpnpConfigAddress();
// strict = theSettings.isUpnpStrict(); // strict = theSettings.isUpnpStrict();
upnpOriginal = theSettings.getBridgeSettingsDescriptor().isUpnporiginal(); upnpOriginal = theSettings.getBridgeSettingsDescriptor().isUpnporiginal();
upnpAdvanced = theSettings.getBridgeSettingsDescriptor().isUpnpadvanced();
traceupnp = theSettings.getBridgeSettingsDescriptor().isTraceupnp(); traceupnp = theSettings.getBridgeSettingsDescriptor().isTraceupnp();
useUpnpIface = theSettings.getBridgeSettingsDescriptor().isUseupnpiface(); useUpnpIface = theSettings.getBridgeSettingsDescriptor().isUseupnpiface();
theUpnpSendDelay = theSettings.getBridgeSettingsDescriptor().getUpnpsenddelay(); theUpnpSendDelay = theSettings.getBridgeSettingsDescriptor().getUpnpsenddelay();
@@ -192,10 +200,13 @@ public class UpnpListener {
log.info("UPNP Discovery Listener running and ready...."); log.info("UPNP Discovery Listener running and ready....");
boolean loopControl = true; boolean loopControl = true;
boolean error = false; boolean error = false;
try {
upnpMulticastSocket.setSoTimeout((int) Configuration.UPNP_NOTIFY_TIMEOUT); if(upnpAdvanced) {
} catch (SocketException e1) { try {
log.warn("Could not sent soTimeout on multi-cast socket"); upnpMulticastSocket.setSoTimeout((int) Configuration.UPNP_NOTIFY_TIMEOUT);
} catch (SocketException e1) {
log.warn("Could not sent soTimeout on multi-cast socket");
}
} }
// Instant current, previous; // Instant current, previous;
// previous = Instant.now(); // previous = Instant.now();
@@ -326,37 +337,39 @@ public class UpnpListener {
+ " with discovery responseTemplate1 is <<<" + discoveryResponse + ">>>"); + " with discovery responseTemplate1 is <<<" + discoveryResponse + ">>>");
sendUDPResponse(discoveryResponse.getBytes(), requester, sourcePort); sendUDPResponse(discoveryResponse.getBytes(), requester, sourcePort);
try { if(upnpAdvanced) {
Thread.sleep(theUpnpSendDelay); try {
} catch (InterruptedException e) { Thread.sleep(theUpnpSendDelay);
// noop } catch (InterruptedException e) {
} // noop
discoveryResponse = String.format(responseTemplate2, Configuration.UPNP_MULTICAST_ADDRESS, }
Configuration.UPNP_DISCOVERY_PORT, httpType, httpLocationAddress, httpServerPort, bridgeId, discoveryResponse = String.format(responseTemplate2, Configuration.UPNP_MULTICAST_ADDRESS,
bridgeSNUUID, bridgeSNUUID); Configuration.UPNP_DISCOVERY_PORT, httpType, httpLocationAddress, httpServerPort, bridgeId,
if (traceupnp) { bridgeSNUUID, bridgeSNUUID);
log.info("Traceupnp: send upnp discovery template 2 with response address: " + httpLocationAddress + ":" if (traceupnp) {
+ httpServerPort + " to address: " + requester.getHostAddress() + ":" + sourcePort); log.info("Traceupnp: send upnp discovery template 2 with response address: " + httpLocationAddress + ":"
} + httpServerPort + " to address: " + requester.getHostAddress() + ":" + sourcePort);
log.debug("sendUpnpResponse to address: " + requester.getHostAddress() + ":" + sourcePort }
+ " discovery responseTemplate2 is <<<" + discoveryResponse + ">>>"); log.debug("sendUpnpResponse to address: " + requester.getHostAddress() + ":" + sourcePort
sendUDPResponse(discoveryResponse.getBytes(), requester, sourcePort); + " discovery responseTemplate2 is <<<" + discoveryResponse + ">>>");
sendUDPResponse(discoveryResponse.getBytes(), requester, sourcePort);
try { try {
Thread.sleep(theUpnpSendDelay); Thread.sleep(theUpnpSendDelay);
} catch (InterruptedException e) { } catch (InterruptedException e) {
// noop // noop
}
discoveryResponse = String.format(responseTemplate3, Configuration.UPNP_MULTICAST_ADDRESS,
Configuration.UPNP_DISCOVERY_PORT, httpType, httpLocationAddress, httpServerPort, bridgeId,
bridgeSNUUID);
if (traceupnp) {
log.info("Traceupnp: send upnp discovery template 3 with response address: " + httpLocationAddress + ":"
+ httpServerPort + " to address: " + requester.getHostAddress() + ":" + sourcePort);
}
log.debug("sendUpnpResponse to address: " + requester.getHostAddress() + ":" + sourcePort
+ " discovery responseTemplate3 is <<<" + discoveryResponse + ">>>");
sendUDPResponse(discoveryResponse.getBytes(), requester, sourcePort);
} }
discoveryResponse = String.format(responseTemplate3, Configuration.UPNP_MULTICAST_ADDRESS,
Configuration.UPNP_DISCOVERY_PORT, httpType, httpLocationAddress, httpServerPort, bridgeId,
bridgeSNUUID);
if (traceupnp) {
log.info("Traceupnp: send upnp discovery template 3 with response address: " + httpLocationAddress + ":"
+ httpServerPort + " to address: " + requester.getHostAddress() + ":" + sourcePort);
}
log.debug("sendUpnpResponse to address: " + requester.getHostAddress() + ":" + sourcePort
+ " discovery responseTemplate3 is <<<" + discoveryResponse + ">>>");
sendUDPResponse(discoveryResponse.getBytes(), requester, sourcePort);
} }
private void sendUDPResponse(byte[] udpMessage, InetAddress requester, int sourcePort) throws IOException { private void sendUDPResponse(byte[] udpMessage, InetAddress requester, int sourcePort) throws IOException {

View File

@@ -55,10 +55,12 @@ public class UpnpSettingsResource {
+ "<depth>24</depth>\n" + "<depth>24</depth>\n"
+ "<url>hue_logo_3.png</url>\n" + "<url>hue_logo_3.png</url>\n"
+ "</icon>\n" + "</icon>\n"
+ "</iconList>\n" + "</iconList>\n";
+ "</device>\n"
+ "</root>\n";
private String hueTemplate_end = "</device>\n"
+ "</root>\n";
/* not utilizing this section any more
private String hueTemplate_mid_orig = "<serviceList>\n" private String hueTemplate_mid_orig = "<serviceList>\n"
+ "<service>\n" + "<service>\n"
+ "<serviceType>(null)</serviceType>\n" + "<serviceType>(null)</serviceType>\n"
@@ -68,7 +70,7 @@ public class UpnpSettingsResource {
+ "<SCPDURL>(null)</SCPDURL>\n" + "<SCPDURL>(null)</SCPDURL>\n"
+ "</service>\n" + "</service>\n"
+ "</serviceList>\n"; + "</serviceList>\n";
*/
public UpnpSettingsResource(BridgeSettings theBridgeSettings) { public UpnpSettingsResource(BridgeSettings theBridgeSettings) {
super(); super();
@@ -92,7 +94,15 @@ public class UpnpSettingsResource {
String hueTemplate = null; String hueTemplate = null;
if(theSettings.isUpnporiginal()) { if(theSettings.isUpnporiginal()) {
httpLocationAddr = theSettings.getUpnpConfigAddress(); httpLocationAddr = theSettings.getUpnpConfigAddress();
hueTemplate = hueTemplate_pre + hueTemplate_mid_orig + hueTemplate_post; hueTemplate = hueTemplate_pre + hueTemplate_end;
} else if(!theSettings.isUpnpadvanced()) {
if(theSettings.isUseupnpiface()) {
httpLocationAddr = theSettings.getUpnpConfigAddress();
} else {
log.debug("Get Outbound address for ip:" + request.ip() + " and port:" + request.port());
httpLocationAddr = AddressUtil.getOutboundAddress(request.ip(), request.port()).getHostAddress();
}
hueTemplate = hueTemplate_pre + hueTemplate_end;
} else { } else {
if(theSettings.isUseupnpiface()) { if(theSettings.isUseupnpiface()) {
@@ -101,7 +111,7 @@ public class UpnpSettingsResource {
log.debug("Get Outbound address for ip:" + request.ip() + " and port:" + request.port()); log.debug("Get Outbound address for ip:" + request.ip() + " and port:" + request.port());
httpLocationAddr = AddressUtil.getOutboundAddress(request.ip(), request.port()).getHostAddress(); httpLocationAddr = AddressUtil.getOutboundAddress(request.ip(), request.port()).getHostAddress();
} }
hueTemplate = hueTemplate_pre + hueTemplate_post; hueTemplate = hueTemplate_pre + hueTemplate_post + hueTemplate_end;
} }
String bridgeIdMac = HuePublicConfig.createConfig("temp", httpLocationAddr, HueConstants.HUB_VERSION, theSettings.getHubmac()).getSNUUIDFromMac(); String bridgeIdMac = HuePublicConfig.createConfig("temp", httpLocationAddr, HueConstants.HUB_VERSION, theSettings.getHubmac()).getSNUUIDFromMac();

View File

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

View File

@@ -114,6 +114,18 @@
ng-model="device.onFirstDim" ng-true-value=true ng-model="device.onFirstDim" ng-true-value=true
ng-false-value=false> {{device.onFirstDim}}</td> ng-false-value=false> {{device.onFirstDim}}</td>
</tr> </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> <tr>
<td><label>Filter Address (comma separated list)</label></td> <td><label>Filter Address (comma separated list)</label></td>
<td><input type="text" class="form-control" id="device-requester-addr" <td><input type="text" class="form-control" id="device-requester-addr"

View File

@@ -824,6 +824,11 @@
<td><input type="checkbox" ng-model="bridge.settings.upnporiginal" ng-true-value=true <td><input type="checkbox" ng-model="bridge.settings.upnporiginal" ng-true-value=true
ng-false-value=false> {{bridge.settings.upnporiginal}}</td> ng-false-value=false> {{bridge.settings.upnporiginal}}</td>
</tr> </tr>
<tr>
<td>UPNP Advanced (use multiple responses and notifies)</td>
<td><input type="checkbox" ng-model="bridge.settings.upnpadvanced" ng-true-value=true
ng-false-value=false> {{bridge.settings.upnpadvanced}}</td>
</tr>
<tr> <tr>
<td>Trace UPNP Calls</td> <td>Trace UPNP Calls</td>
<td><input type="checkbox" ng-model="bridge.settings.traceupnp" ng-true-value=true <td><input type="checkbox" ng-model="bridge.settings.traceupnp" ng-true-value=true
@@ -839,6 +844,11 @@
<td><input id="bridge-settings-upnpsenddelay" class="form-control" type="number" <td><input id="bridge-settings-upnpsenddelay" class="form-control" type="number"
ng-model="bridge.settings.upnpsenddelay" min="100" max="15000"></td> ng-model="bridge.settings.upnpsenddelay" min="100" max="15000"></td>
</tr> </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> <tr>
<td>ID Seed (start numbering from this value)</td> <td>ID Seed (start numbering from this value)</td>
<td><input id="bridge-settings-seedid" class="form-control" type="number" <td><input id="bridge-settings-seedid" class="form-control" type="number"

View File

@@ -1,5 +1,6 @@
package com.bwssystems.color.test; package com.bwssystems.color.test;
import java.awt.Color;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@@ -17,10 +18,10 @@ public class ConvertCIEColorTestCase {
@Test @Test
public void testColorConverterXYtoRGB() { 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(); XYColorSpace xyColor = new XYColorSpace();
xyColor.setBrightness(50); xyColor.setBrightness(56);
float[] xyFloat = new float[2]; float[] xyFloat = new float[2];
xyFloat[0] = xy.get(0).floatValue(); xyFloat[0] = xy.get(0).floatValue();
xyFloat[1] = xy.get(1).floatValue(); xyFloat[1] = xy.get(1).floatValue();
@@ -32,12 +33,29 @@ public class ConvertCIEColorTestCase {
rgbDecode.add(1, rgb[1]); rgbDecode.add(1, rgb[1]);
rgbDecode.add(2, rgb[2]); rgbDecode.add(2, rgb[2]);
List<Integer> assertDecode = new ArrayList<Integer>(); List<Integer> assertDecode = new ArrayList<Integer>();
assertDecode.add(0, 255); assertDecode.add(0, 60);
assertDecode.add(1, 0); assertDecode.add(1, 134);
assertDecode.add(2, 5); assertDecode.add(2, 196);
Assert.assertEquals(rgbDecode, assertDecode); 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 @Test
public void testColorConversionXYtoRGB1() { public void testColorConversionXYtoRGB1() {
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.671254"), Double.parseDouble("0.303273")));
@@ -70,6 +88,22 @@ public class ConvertCIEColorTestCase {
Assert.assertEquals(rgbIntVal, 15270119); 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 @Test
public void testColorConversionHSBtoRGB1() { public void testColorConversionHSBtoRGB1() {
HueSatBri hsb = new HueSatBri(); HueSatBri hsb = new HueSatBri();
@@ -79,12 +113,30 @@ public class ConvertCIEColorTestCase {
List<Integer> colorDecode = ColorDecode.convertHSBtoRGB(hsb); List<Integer> colorDecode = ColorDecode.convertHSBtoRGB(hsb);
List<Integer> assertDecode = new ArrayList<Integer>(); List<Integer> assertDecode = new ArrayList<Integer>();
assertDecode.add(0, 60); assertDecode.add(0, 61);
assertDecode.add(1, 97); assertDecode.add(1, 134);
assertDecode.add(2, 128); assertDecode.add(2, 196);
Assert.assertEquals(colorDecode, assertDecode); 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 @Test
public void testColorConversionCTtoRGB() { public void testColorConversionCTtoRGB() {
Integer ct = 500; Integer ct = 500;