From 3f9e4f6b1fc1039f55e2331c4fc4205945baf8f5 Mon Sep 17 00:00:00 2001 From: Alexander Kostadinov Date: Wed, 20 Jun 2018 13:04:43 +0300 Subject: [PATCH] Implemented Color Mode channel for the Extended Color Light. Signed-off-by: Alexander Kostadinov --- .../hue/handler/HueLightHandlerTest.java | 10 ++++- .../ESH-INF/thing/ExtendedColorLight.xml | 1 + .../ESH-INF/thing/channels.xml | 13 ++++++ .../binding/hue/HueBindingConstants.java | 1 + .../binding/hue/handler/HueLightHandler.java | 44 +++++++++++++++++++ .../hue/handler/LightStateConverter.java | 27 ++++++++++++ 6 files changed, 95 insertions(+), 1 deletion(-) diff --git a/extensions/binding/org.eclipse.smarthome.binding.hue.test/src/test/java/org/eclipse/smarthome/binding/hue/handler/HueLightHandlerTest.java b/extensions/binding/org.eclipse.smarthome.binding.hue.test/src/test/java/org/eclipse/smarthome/binding/hue/handler/HueLightHandlerTest.java index 41dbc94e5a6..aeb9ae9c434 100644 --- a/extensions/binding/org.eclipse.smarthome.binding.hue.test/src/test/java/org/eclipse/smarthome/binding/hue/handler/HueLightHandlerTest.java +++ b/extensions/binding/org.eclipse.smarthome.binding.hue.test/src/test/java/org/eclipse/smarthome/binding/hue/handler/HueLightHandlerTest.java @@ -33,6 +33,7 @@ import org.eclipse.smarthome.core.thing.ChannelUID; import org.eclipse.smarthome.core.thing.Thing; import org.eclipse.smarthome.core.thing.ThingStatus; +import org.eclipse.smarthome.core.thing.ThingTypeUID; import org.eclipse.smarthome.core.thing.ThingUID; import org.eclipse.smarthome.core.types.Command; import org.junit.Before; @@ -342,7 +343,9 @@ private void assertSendCommand(String channel, Command command, HueLightState cu Thing mockThing = mock(Thing.class); when(mockThing.getConfiguration()).thenReturn(new Configuration(Collections.singletonMap(LIGHT_ID, "1"))); - + when(mockThing.getUID()).thenReturn(new ThingUID(BINDING_ID, expectedModel)); + when(mockThing.getThingTypeUID()).thenReturn(new ThingTypeUID(BINDING_ID, expectedModel)); + HueClient mockClient = mock(HueClient.class); when(mockClient.getLightById(any())).thenReturn(light); @@ -356,6 +359,11 @@ protected synchronized HueClient getHueClient() { protected Bridge getBridge() { return mockBridge; } + + @Override + public Thing getThing() { + return mockThing; + } }; hueLightHandler.initialize(); diff --git a/extensions/binding/org.eclipse.smarthome.binding.hue/ESH-INF/thing/ExtendedColorLight.xml b/extensions/binding/org.eclipse.smarthome.binding.hue/ESH-INF/thing/ExtendedColorLight.xml index 8e2da5b0dce..d4d140cfb38 100644 --- a/extensions/binding/org.eclipse.smarthome.binding.hue/ESH-INF/thing/ExtendedColorLight.xml +++ b/extensions/binding/org.eclipse.smarthome.binding.hue/ESH-INF/thing/ExtendedColorLight.xml @@ -17,6 +17,7 @@ + uniqueId diff --git a/extensions/binding/org.eclipse.smarthome.binding.hue/ESH-INF/thing/channels.xml b/extensions/binding/org.eclipse.smarthome.binding.hue/ESH-INF/thing/channels.xml index 10e167cc073..2a4945a3b51 100644 --- a/extensions/binding/org.eclipse.smarthome.binding.hue/ESH-INF/thing/channels.xml +++ b/extensions/binding/org.eclipse.smarthome.binding.hue/ESH-INF/thing/channels.xml @@ -73,4 +73,17 @@ The effect channel allows putting the bulb in a color looping mode. ColorLight + + + + String + + The color mode channel denotes if the bulb is in a Color or Color Temperature mode. + + + + + + + diff --git a/extensions/binding/org.eclipse.smarthome.binding.hue/src/main/java/org/eclipse/smarthome/binding/hue/HueBindingConstants.java b/extensions/binding/org.eclipse.smarthome.binding.hue/src/main/java/org/eclipse/smarthome/binding/hue/HueBindingConstants.java index 3de85d02042..5bd5f7353e5 100644 --- a/extensions/binding/org.eclipse.smarthome.binding.hue/src/main/java/org/eclipse/smarthome/binding/hue/HueBindingConstants.java +++ b/extensions/binding/org.eclipse.smarthome.binding.hue/src/main/java/org/eclipse/smarthome/binding/hue/HueBindingConstants.java @@ -49,6 +49,7 @@ public class HueBindingConstants { public static final String CHANNEL_ALERT = "alert"; public static final String CHANNEL_EFFECT = "effect"; public static final String CHANNEL_SWITCH = "switch"; + public static final String CHANNEL_COLORMODE = "color_mode"; // Bridge config properties public static final String HOST = "ipAddress"; diff --git a/extensions/binding/org.eclipse.smarthome.binding.hue/src/main/java/org/eclipse/smarthome/binding/hue/handler/HueLightHandler.java b/extensions/binding/org.eclipse.smarthome.binding.hue/src/main/java/org/eclipse/smarthome/binding/hue/handler/HueLightHandler.java index ed1d21554c3..29ac22e0baf 100644 --- a/extensions/binding/org.eclipse.smarthome.binding.hue/src/main/java/org/eclipse/smarthome/binding/hue/handler/HueLightHandler.java +++ b/extensions/binding/org.eclipse.smarthome.binding.hue/src/main/java/org/eclipse/smarthome/binding/hue/handler/HueLightHandler.java @@ -29,6 +29,7 @@ import org.eclipse.smarthome.binding.hue.internal.FullLight; import org.eclipse.smarthome.binding.hue.internal.HueBridge; import org.eclipse.smarthome.binding.hue.internal.State; +import org.eclipse.smarthome.binding.hue.internal.State.ColorMode; import org.eclipse.smarthome.binding.hue.internal.StateUpdate; import org.eclipse.smarthome.core.library.types.HSBType; import org.eclipse.smarthome.core.library.types.IncreaseDecreaseType; @@ -36,6 +37,7 @@ import org.eclipse.smarthome.core.library.types.PercentType; import org.eclipse.smarthome.core.library.types.StringType; import org.eclipse.smarthome.core.thing.Bridge; +import org.eclipse.smarthome.core.thing.Channel; import org.eclipse.smarthome.core.thing.ChannelUID; import org.eclipse.smarthome.core.thing.Thing; import org.eclipse.smarthome.core.thing.ThingStatus; @@ -43,6 +45,9 @@ import org.eclipse.smarthome.core.thing.ThingTypeUID; import org.eclipse.smarthome.core.thing.binding.BaseThingHandler; import org.eclipse.smarthome.core.thing.binding.ThingHandler; +import org.eclipse.smarthome.core.thing.binding.builder.ChannelBuilder; +import org.eclipse.smarthome.core.thing.binding.builder.ThingBuilder; +import org.eclipse.smarthome.core.thing.type.ChannelTypeUID; import org.eclipse.smarthome.core.types.Command; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -125,6 +130,11 @@ private void initializeThing(@Nullable ThingStatus bridgeStatus) { if (getHueClient() != null) { if (bridgeStatus == ThingStatus.ONLINE) { initializeProperties(); + + if (colorModeChannelRequired()) { + addColorModeChannel(); + } + updateStatus(ThingStatus.ONLINE); } else { updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE); @@ -422,6 +432,14 @@ public void onLightStateChanged(@Nullable HueBridge bridge, FullLight fullLight) updateState(CHANNEL_ALERT, stringType); scheduleAlertStateRestore(stringType); } + + ColorMode colorMode = fullLight.getState().getColorMode(); + if (colorMode != null) { + updateState(CHANNEL_COLORMODE, LightStateConverter.toColorModeStringType(colorMode)); + } else { + // By default fall back to pure Hue & Saturation color mode + updateState(CHANNEL_COLORMODE, LightStateConverter.toColorModeStringType(ColorMode.HS)); + } } @Override @@ -512,4 +530,30 @@ private int getAlertDuration(Command command) { return delay; } + + /** + * Performs a check if the color_mode channel needs to + * be added to the remote thing + * @return true if the thing type is 0210 and + * the color_mode channel is missing + */ + private boolean colorModeChannelRequired() { + ChannelUID colorModeChannelUID = new ChannelUID(getThing().getUID(), CHANNEL_COLORMODE); + return (getThing().getThingTypeUID().equals(THING_TYPE_EXTENDED_COLOR_LIGHT)) + && (getThing().getChannel(colorModeChannelUID.getAsString()) == null); + } + + /** + * Creates the color_mode channel for + * an already paired remote thing + */ + private void addColorModeChannel() { + ChannelUID colorModeChannelUID = new ChannelUID(getThing().getUID(), CHANNEL_COLORMODE); + + Channel colorModeChannel = ChannelBuilder.create(colorModeChannelUID, "String") + .withType(new ChannelTypeUID(BINDING_ID, CHANNEL_COLORMODE)).build(); + + ThingBuilder thingBuilder = editThing().withChannel(colorModeChannel); + updateThing(thingBuilder.build()); + } } diff --git a/extensions/binding/org.eclipse.smarthome.binding.hue/src/main/java/org/eclipse/smarthome/binding/hue/handler/LightStateConverter.java b/extensions/binding/org.eclipse.smarthome.binding.hue/src/main/java/org/eclipse/smarthome/binding/hue/handler/LightStateConverter.java index 2e4c4f51fa9..e9ca3dc7b6a 100644 --- a/extensions/binding/org.eclipse.smarthome.binding.hue/src/main/java/org/eclipse/smarthome/binding/hue/handler/LightStateConverter.java +++ b/extensions/binding/org.eclipse.smarthome.binding.hue/src/main/java/org/eclipse/smarthome/binding/hue/handler/LightStateConverter.java @@ -16,6 +16,7 @@ import org.eclipse.jdt.annotation.Nullable; import org.eclipse.smarthome.binding.hue.internal.State; import org.eclipse.smarthome.binding.hue.internal.State.AlertMode; +import org.eclipse.smarthome.binding.hue.internal.State.ColorMode; import org.eclipse.smarthome.binding.hue.internal.State.Effect; import org.eclipse.smarthome.binding.hue.internal.StateUpdate; import org.eclipse.smarthome.core.library.types.DecimalType; @@ -47,6 +48,9 @@ public class LightStateConverter { private static final int MIN_COLOR_TEMPERATURE = 153; private static final int MAX_COLOR_TEMPERATURE = 500; private static final int COLOR_TEMPERATURE_RANGE = MAX_COLOR_TEMPERATURE - MIN_COLOR_TEMPERATURE; + + public static final String COLORMODE_COLOR = "COLOR"; + public static final String COLORMODE_COLOR_TEMPERATURE = "COLOR_TEMPERATURE"; /** * {@value #ALERT_MODE_NONE}. The light is not performing an alert effect. @@ -265,6 +269,29 @@ public static StateUpdate toOnOffEffectState(OnOffType onOffType) { return stateUpdate; } + + /** + * Transforms a given {@link ColorMode} to its corresponding {@link StringType} as follows: + * Supported values are: + *
    + *
  • XY (CIE color space coordinates) and HS (Hue & saturation) color modes are mapped to {@link #COLORMODE_COLOR} + *
  • CT (color temperature) color mode is mapped to {@link #COLORMODE_COLOR_TEMPERATURE} + *
      + * + * @param {@link ColorMode} colorMode + * @return A {@link StringType} representing the given ColorMode + */ + public static StringType toColorModeStringType(@Nullable ColorMode colorMode) { + switch (colorMode) { + case XY: + case HS: + return new StringType(COLORMODE_COLOR); + case CT: + return new StringType(COLORMODE_COLOR_TEMPERATURE); + default: + return new StringType(COLORMODE_COLOR); + } + } private static int restrictToBounds(int percentValue) { if (percentValue < 0) {