[avmfritz] Allow to set every userdefined color (#13317)
* Added INCREASE/DECREASE commands for brightness/color Channels * Fixed NPE in HeatingModel * Use set unmapped color command for color control of bulbs Signed-off-by: Christoph Weitkamp <github@christophweitkamp.de>
This commit is contained in:
parent
df432a7fbc
commit
32c76898c1
|
@ -15,8 +15,10 @@ package org.openhab.binding.avmfritz.internal.dto;
|
||||||
import javax.xml.bind.annotation.XmlAccessType;
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
import javax.xml.bind.annotation.XmlAccessorType;
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
import javax.xml.bind.annotation.XmlAttribute;
|
import javax.xml.bind.annotation.XmlAttribute;
|
||||||
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
import org.openhab.core.library.types.PercentType;
|
import org.openhab.core.library.types.PercentType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -36,6 +38,10 @@ public class ColorControlModel {
|
||||||
public int currentMode;
|
public int currentMode;
|
||||||
public int hue;
|
public int hue;
|
||||||
public int saturation;
|
public int saturation;
|
||||||
|
@XmlElement(name = "unmapped_hue")
|
||||||
|
public @Nullable Integer unmappedHue;
|
||||||
|
@XmlElement(name = "unmapped_saturation")
|
||||||
|
public @Nullable Integer unmappedSaturation;
|
||||||
public int temperature;
|
public int temperature;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -62,7 +68,8 @@ public class ColorControlModel {
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return new StringBuilder("[supportedModes=").append(supportedModes).append(",currentMode=").append(currentMode)
|
return new StringBuilder("[supportedModes=").append(supportedModes).append(",currentMode=").append(currentMode)
|
||||||
.append(",hue=").append(hue).append(",saturation=").append(saturation).append(",temperature=")
|
.append(",hue=").append(hue).append(",saturation=").append(saturation).append(",unmapped_hue=")
|
||||||
|
.append(unmappedHue).append(",unmapped_saturation=").append(unmappedSaturation).append(",temperature=")
|
||||||
.append(temperature).append("]").toString();
|
.append(temperature).append("]").toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -111,9 +111,9 @@ public class HeatingModel implements BatteryModel {
|
||||||
return MODE_OFF;
|
return MODE_OFF;
|
||||||
} else if (BigDecimal.ONE.equals(getWindowopenactiv())) {
|
} else if (BigDecimal.ONE.equals(getWindowopenactiv())) {
|
||||||
return MODE_WINDOW_OPEN;
|
return MODE_WINDOW_OPEN;
|
||||||
} else if (tsoll.compareTo(komfort) == 0) {
|
} else if (komfort != null && komfort.compareTo(tsoll) == 0) {
|
||||||
return MODE_COMFORT;
|
return MODE_COMFORT;
|
||||||
} else if (tsoll.compareTo(absenk) == 0) {
|
} else if (absenk != null && absenk.compareTo(tsoll) == 0) {
|
||||||
return MODE_ECO;
|
return MODE_ECO;
|
||||||
} else if (BigDecimal.ONE.equals(getBoostactive()) || TEMP_FRITZ_MAX.compareTo(tsoll) == 0) {
|
} else if (BigDecimal.ONE.equals(getBoostactive()) || TEMP_FRITZ_MAX.compareTo(tsoll) == 0) {
|
||||||
return MODE_BOOST;
|
return MODE_BOOST;
|
||||||
|
|
|
@ -411,12 +411,19 @@ public abstract class AVMFritzBaseThingHandler extends BaseThingHandler implemen
|
||||||
if (command instanceof HSBType) {
|
if (command instanceof HSBType) {
|
||||||
HSBType hsbType = (HSBType) command;
|
HSBType hsbType = (HSBType) command;
|
||||||
brightness = hsbType.getBrightness().toBigDecimal();
|
brightness = hsbType.getBrightness().toBigDecimal();
|
||||||
fritzBox.setHueAndSaturation(ain, hsbType.getHue().intValue(),
|
fritzBox.setUnmappedHueAndSaturation(ain, hsbType.getHue().intValue(),
|
||||||
ColorControlModel.fromPercent(hsbType.getSaturation()), 0);
|
ColorControlModel.fromPercent(hsbType.getSaturation()), 0);
|
||||||
} else if (command instanceof PercentType) {
|
} else if (command instanceof PercentType) {
|
||||||
brightness = ((PercentType) command).toBigDecimal();
|
brightness = ((PercentType) command).toBigDecimal();
|
||||||
} else if (command instanceof OnOffType) {
|
} else if (command instanceof OnOffType) {
|
||||||
fritzBox.setSwitch(ain, OnOffType.ON.equals(command));
|
fritzBox.setSwitch(ain, OnOffType.ON.equals(command));
|
||||||
|
} else if (command instanceof IncreaseDecreaseType) {
|
||||||
|
brightness = ((DeviceModel) currentDevice).getLevelControlModel().getLevelPercentage();
|
||||||
|
if (IncreaseDecreaseType.INCREASE.equals(command)) {
|
||||||
|
brightness.add(BigDecimal.TEN);
|
||||||
|
} else {
|
||||||
|
brightness.subtract(BigDecimal.TEN);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (brightness != null) {
|
if (brightness != null) {
|
||||||
fritzBox.setLevelPercentage(ain, brightness);
|
fritzBox.setLevelPercentage(ain, brightness);
|
||||||
|
|
|
@ -330,11 +330,16 @@ public class FritzAhaWebInterface {
|
||||||
return asyncGet(callback);
|
return asyncGet(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FritzAhaContentExchange setHueAndSaturation(String ain, int hue, int saturation, int duration) {
|
public FritzAhaContentExchange setMappedHueAndSaturation(String ain, int hue, int saturation, int duration) {
|
||||||
FritzAhaSetColorCallback callback = new FritzAhaSetColorCallback(this, ain, hue, saturation, duration);
|
FritzAhaSetColorCallback callback = new FritzAhaSetColorCallback(this, ain, hue, saturation, duration);
|
||||||
return asyncGet(callback);
|
return asyncGet(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public FritzAhaContentExchange setUnmappedHueAndSaturation(String ain, int hue, int saturation, int duration) {
|
||||||
|
FritzAhaSetColorCallback callback = new FritzAhaSetColorCallback(this, ain, hue, saturation, duration, false);
|
||||||
|
return asyncGet(callback);
|
||||||
|
}
|
||||||
|
|
||||||
public FritzAhaContentExchange setBlind(String ain, BlindCommand command) {
|
public FritzAhaContentExchange setBlind(String ain, BlindCommand command) {
|
||||||
FritzAhaSetBlindTargetCallback callback = new FritzAhaSetBlindTargetCallback(this, ain, command);
|
FritzAhaSetBlindTargetCallback callback = new FritzAhaSetBlindTargetCallback(this, ain, command);
|
||||||
return asyncGet(callback);
|
return asyncGet(callback);
|
||||||
|
|
|
@ -27,6 +27,9 @@ import org.slf4j.LoggerFactory;
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
public class FritzAhaSetColorCallback extends FritzAhaReauthCallback {
|
public class FritzAhaSetColorCallback extends FritzAhaReauthCallback {
|
||||||
|
|
||||||
|
private static final String WEBSERVICE_SET_COLOR_COMMAND = "switchcmd=setcolor";
|
||||||
|
private static final String WEBSERVICE_SET_UNMAPPED_COLOR_COMMAND = "switchcmd=setunmappedcolor";
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(FritzAhaSetColorCallback.class);
|
private final Logger logger = LoggerFactory.getLogger(FritzAhaSetColorCallback.class);
|
||||||
|
|
||||||
private final String ain;
|
private final String ain;
|
||||||
|
@ -41,8 +44,25 @@ public class FritzAhaSetColorCallback extends FritzAhaReauthCallback {
|
||||||
* @param duration Duration of the change in 100ms. 0 immediately.
|
* @param duration Duration of the change in 100ms. 0 immediately.
|
||||||
*/
|
*/
|
||||||
public FritzAhaSetColorCallback(FritzAhaWebInterface webIface, String ain, int hue, int saturation, int duration) {
|
public FritzAhaSetColorCallback(FritzAhaWebInterface webIface, String ain, int hue, int saturation, int duration) {
|
||||||
|
this(webIface, ain, hue, saturation, duration, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param webIface Interface to FRITZ!Box
|
||||||
|
* @param ain AIN of the device that should be switched
|
||||||
|
* @param hue New hue
|
||||||
|
* @param saturation New saturation
|
||||||
|
* @param duration Duration of the change in 100ms. 0 immediately.
|
||||||
|
* @param mapped Use mapped or unmapped color command
|
||||||
|
*/
|
||||||
|
public FritzAhaSetColorCallback(FritzAhaWebInterface webIface, String ain, int hue, int saturation, int duration,
|
||||||
|
boolean mapped) {
|
||||||
super(WEBSERVICE_PATH,
|
super(WEBSERVICE_PATH,
|
||||||
"switchcmd=setcolor&ain=" + ain + "&hue=" + hue + "&saturation=" + saturation + "&duration=" + duration,
|
mapped ? WEBSERVICE_SET_COLOR_COMMAND
|
||||||
|
: WEBSERVICE_SET_UNMAPPED_COLOR_COMMAND + "&ain=" + ain + "&hue=" + hue + "&saturation="
|
||||||
|
+ saturation + "&duration=" + duration,
|
||||||
webIface, GET, 1);
|
webIface, GET, 1);
|
||||||
this.ain = ain;
|
this.ain = ain;
|
||||||
}
|
}
|
||||||
|
|
|
@ -725,6 +725,8 @@ public class AVMFritzDeviceListModelTest {
|
||||||
assertNotNull(colorModel);
|
assertNotNull(colorModel);
|
||||||
assertEquals(254, colorModel.hue);
|
assertEquals(254, colorModel.hue);
|
||||||
assertEquals(100, colorModel.saturation);
|
assertEquals(100, colorModel.saturation);
|
||||||
|
assertEquals(0, colorModel.unmappedHue);
|
||||||
|
assertEquals(0, colorModel.unmappedSaturation);
|
||||||
assertEquals(2700, colorModel.temperature);
|
assertEquals(2700, colorModel.temperature);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,16 @@ class ColorControlModelTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testColorControlModelPercentConversionRestrictsToLowerBounds() {
|
||||||
|
assertThat(ColorControlModel.toPercent(-1), is(PercentType.ZERO));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testColorControlModelPercentConversionRestrictsToUpperBounds() {
|
||||||
|
assertThat(ColorControlModel.toPercent(999), is(PercentType.HUNDRED));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void hsbSaturationAlwaysGreaterThanZero() {
|
public void hsbSaturationAlwaysGreaterThanZero() {
|
||||||
// a saturation greater than 1 should result in a percentage greater than 1
|
// a saturation greater than 1 should result in a percentage greater than 1
|
||||||
|
|
|
@ -12,7 +12,8 @@
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.avmfritz.internal.dto;
|
package org.openhab.binding.avmfritz.internal.dto;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.openhab.binding.avmfritz.internal.AVMFritzBindingConstants.*;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
@ -60,4 +61,16 @@ public class HeatingModelTest {
|
||||||
assertEquals(BIGDECIMAL_FOURTEEN_POINT_FIVE, HeatingModel.normalizeCelsius(new BigDecimal("14.4")));
|
assertEquals(BIGDECIMAL_FOURTEEN_POINT_FIVE, HeatingModel.normalizeCelsius(new BigDecimal("14.4")));
|
||||||
assertEquals(BIGDECIMAL_FOURTEEN_POINT_FIVE, HeatingModel.normalizeCelsius(new BigDecimal("14.6")));
|
assertEquals(BIGDECIMAL_FOURTEEN_POINT_FIVE, HeatingModel.normalizeCelsius(new BigDecimal("14.6")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void validateGetRadiatorModeReturnsValidMode() {
|
||||||
|
HeatingModel heatingModel = new HeatingModel();
|
||||||
|
assertEquals(MODE_UNKNOWN, heatingModel.getRadiatorMode());
|
||||||
|
|
||||||
|
heatingModel.setTsoll(BigDecimal.ONE);
|
||||||
|
assertEquals(MODE_ON, heatingModel.getRadiatorMode());
|
||||||
|
|
||||||
|
heatingModel.setKomfort(BigDecimal.ONE);
|
||||||
|
assertEquals(MODE_COMFORT, heatingModel.getRadiatorMode());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue