Skip to content

Commit

Permalink
[Hue] Implemented fade time (openhab#4660)
Browse files Browse the repository at this point in the history
Implemented fade time config for light things.
Implemented ThingAction fadingLightCommand for Hue lights
Updated README.md

Bug: openhab#1722
Signed-off-by: Jochen [email protected]
Signed-off-by: Maximilian Hess <[email protected]>
  • Loading branch information
xLAva authored and ne0h committed Sep 15, 2019
1 parent fb208b2 commit c24244d
Show file tree
Hide file tree
Showing 14 changed files with 247 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -99,43 +99,43 @@ public void assertCommandForOsramPar16_50ForBrightnessChannelOff() {

@Test
public void assertCommandForColorChannelOn() {
String expectedReply = "{\"on\" : true}";
String expectedReply = "{\"on\" : true, \"transitiontime\" : 4}";
assertSendCommandForColor(OnOffType.ON, new HueLightState(), expectedReply);
}

@Test
public void assertCommandForColorTemperatureChannelOn() {
String expectedReply = "{\"on\" : true}";
String expectedReply = "{\"on\" : true, \"transitiontime\" : 4}";
assertSendCommandForColorTemp(OnOffType.ON, new HueLightState(), expectedReply);
}

@Test
public void assertCommandForColorChannelOff() {
String expectedReply = "{\"on\" : false}";
String expectedReply = "{\"on\" : false, \"transitiontime\" : 4}";
assertSendCommandForColor(OnOffType.OFF, new HueLightState(), expectedReply);
}

@Test
public void assertCommandForColorTemperatureChannelOff() {
String expectedReply = "{\"on\" : false}";
String expectedReply = "{\"on\" : false, \"transitiontime\" : 4}";
assertSendCommandForColorTemp(OnOffType.OFF, new HueLightState(), expectedReply);
}

@Test
public void assertCommandForColorTemperatureChannel0Percent() {
String expectedReply = "{\"ct\" : 153}";
String expectedReply = "{\"ct\" : 153, \"transitiontime\" : 4}";
assertSendCommandForColorTemp(new PercentType(0), new HueLightState(), expectedReply);
}

@Test
public void assertCommandForColorTemperatureChannel50Percent() {
String expectedReply = "{\"ct\" : 327}";
String expectedReply = "{\"ct\" : 327, \"transitiontime\" : 4}";
assertSendCommandForColorTemp(new PercentType(50), new HueLightState(), expectedReply);
}

@Test
public void assertCommandForColorTemperatureChannel1000Percent() {
String expectedReply = "{\"ct\" : 500}";
String expectedReply = "{\"ct\" : 500, \"transitiontime\" : 4}";
assertSendCommandForColorTemp(new PercentType(100), new HueLightState(), expectedReply);
}

Expand All @@ -159,140 +159,140 @@ public void assertPercentageValueOfColorTemperatureWhenCt500() {

@Test
public void assertCommandForColorChannel0Percent() {
String expectedReply = "{\"on\" : false}";
String expectedReply = "{\"on\" : false, \"transitiontime\" : 4}";
assertSendCommandForColor(new PercentType(0), new HueLightState(), expectedReply);
}

@Test
public void assertCommandForColorChannel50Percent() {
String expectedReply = "{\"bri\" : 127, \"on\" : true}";
String expectedReply = "{\"bri\" : 127, \"on\" : true, \"transitiontime\" : 4}";
assertSendCommandForColor(new PercentType(50), new HueLightState(), expectedReply);
}

@Test
public void assertCommandForColorChannel100Percent() {
String expectedReply = "{\"bri\" : 254, \"on\" : true}";
String expectedReply = "{\"bri\" : 254, \"on\" : true, \"transitiontime\" : 4}";
assertSendCommandForColor(new PercentType(100), new HueLightState(), expectedReply);
}

@Test
public void assertCommandForColorChannelBlack() {
String expectedReply = "{\"on\" : false}";
String expectedReply = "{\"on\" : false, \"transitiontime\" : 4}";
assertSendCommandForColor(HSBType.BLACK, new HueLightState(), expectedReply);
}

@Test
public void assertCommandForColorChannelRed() {
String expectedReply = "{\"bri\" : 254, \"sat\" : 254, \"hue\" : 0}";
String expectedReply = "{\"bri\" : 254, \"sat\" : 254, \"hue\" : 0, \"transitiontime\" : 4}";
assertSendCommandForColor(HSBType.RED, new HueLightState(), expectedReply);
}

@Test
public void assertCommandForColorChannelGreen() {
String expectedReply = "{\"bri\" : 254, \"sat\" : 254, \"hue\" : 21845}";
String expectedReply = "{\"bri\" : 254, \"sat\" : 254, \"hue\" : 21845, \"transitiontime\" : 4}";
assertSendCommandForColor(HSBType.GREEN, new HueLightState(), expectedReply);
}

@Test
public void assertCommandForColorChannelBlue() {
String expectedReply = "{\"bri\" : 254, \"sat\" : 254, \"hue\" : 43690}";
String expectedReply = "{\"bri\" : 254, \"sat\" : 254, \"hue\" : 43690, \"transitiontime\" : 4}";
assertSendCommandForColor(HSBType.BLUE, new HueLightState(), expectedReply);
}

@Test
public void assertCommandForColorChannelWhite() {
String expectedReply = "{\"bri\" : 254, \"sat\" : 0, \"hue\" : 0}";
String expectedReply = "{\"bri\" : 254, \"sat\" : 0, \"hue\" : 0, \"transitiontime\" : 4}";
assertSendCommandForColor(HSBType.WHITE, new HueLightState(), expectedReply);
}

@Test
public void assertXYCommandForColorChannelBlack() {
String expectedReply = "{\"on\" : false}";
String expectedReply = "{\"on\" : false, \"transitiontime\" : 4}";
assertSendCommandForColor(HSBType.BLACK, new HueLightState().colormode(ColorMode.XY), expectedReply);
}

@Test
public void assertXYCommandForColorChannelWhite() {
String expectedReply = "{\"xy\" : [ 0.31271592 , 0.32900152 ], \"bri\" : 254}";
String expectedReply = "{\"xy\" : [ 0.31271592 , 0.32900152 ], \"bri\" : 254, \"transitiontime\" : 4}";
assertSendCommandForColor(HSBType.WHITE, new HueLightState().colormode(ColorMode.XY), expectedReply);
}

@Test
public void assertXYCommandForColorChannelColorful() {
String expectedReply = "{\"xy\" : [ 0.16969365 , 0.12379659 ], \"bri\" : 127}";
String expectedReply = "{\"xy\" : [ 0.16969365 , 0.12379659 ], \"bri\" : 127, \"transitiontime\" : 4}";
assertSendCommandForColor(new HSBType("220,90,50"), new HueLightState().colormode(ColorMode.XY), expectedReply);
}

@Test
public void asserCommandForColorChannelIncrease() {
HueLightState currentState = new HueLightState().bri(1).on(false);
String expectedReply = "{\"bri\" : 30, \"on\" : true}";
String expectedReply = "{\"bri\" : 30, \"on\" : true, \"transitiontime\" : 4}";
assertSendCommandForColor(IncreaseDecreaseType.INCREASE, currentState, expectedReply);

currentState.bri(200).on(true);
expectedReply = "{\"bri\" : 230}";
expectedReply = "{\"bri\" : 230, \"transitiontime\" : 4}";
assertSendCommandForColor(IncreaseDecreaseType.INCREASE, currentState, expectedReply);

currentState.bri(230);
expectedReply = "{\"bri\" : 254}";
expectedReply = "{\"bri\" : 254, \"transitiontime\" : 4}";
assertSendCommandForColor(IncreaseDecreaseType.INCREASE, currentState, expectedReply);
}

@Test
public void asserCommandForColorChannelDecrease() {
HueLightState currentState = new HueLightState().bri(200);
String expectedReply = "{\"bri\" : 170}";
String expectedReply = "{\"bri\" : 170, \"transitiontime\" : 4}";
assertSendCommandForColor(IncreaseDecreaseType.DECREASE, currentState, expectedReply);

currentState.bri(20);
expectedReply = "{\"on\" : false}";
expectedReply = "{\"on\" : false, \"transitiontime\" : 4}";
assertSendCommandForColor(IncreaseDecreaseType.DECREASE, currentState, expectedReply);
}

@Test
public void assertCommandForBrightnessChannel50Percent() {
HueLightState currentState = new HueLightState();
String expectedReply = "{\"bri\" : 127, \"on\" : true}";
String expectedReply = "{\"bri\" : 127, \"on\" : true, \"transitiontime\" : 4}";
assertSendCommandForBrightness(new PercentType(50), currentState, expectedReply);
}

@Test
public void assertCommandForBrightnessChannelIncrease() {
HueLightState currentState = new HueLightState().bri(1).on(false);
String expectedReply = "{\"bri\" : 30, \"on\" : true}";
String expectedReply = "{\"bri\" : 30, \"on\" : true, \"transitiontime\" : 4}";
assertSendCommandForBrightness(IncreaseDecreaseType.INCREASE, currentState, expectedReply);

currentState.bri(200).on(true);
expectedReply = "{\"bri\" : 230}";
expectedReply = "{\"bri\" : 230, \"transitiontime\" : 4}";
assertSendCommandForBrightness(IncreaseDecreaseType.INCREASE, currentState, expectedReply);

currentState.bri(230);
expectedReply = "{\"bri\" : 254}";
expectedReply = "{\"bri\" : 254, \"transitiontime\" : 4}";
assertSendCommandForBrightness(IncreaseDecreaseType.INCREASE, currentState, expectedReply);
}

@Test
public void assertCommandForBrightnessChannelDecrease() {
HueLightState currentState = new HueLightState().bri(200);
String expectedReply = "{\"bri\" : 170}";
String expectedReply = "{\"bri\" : 170, \"transitiontime\" : 4}";
assertSendCommandForBrightness(IncreaseDecreaseType.DECREASE, currentState, expectedReply);

currentState.bri(20);
expectedReply = "{\"on\" : false}";
expectedReply = "{\"on\" : false, \"transitiontime\" : 4}";
assertSendCommandForBrightness(IncreaseDecreaseType.DECREASE, currentState, expectedReply);
}

@Test
public void assertCommandForBrightnessChannelOff() {
HueLightState currentState = new HueLightState();
String expectedReply = "{\"on\" : false}";
String expectedReply = "{\"on\" : false, \"transitiontime\" : 4}";
assertSendCommandForBrightness(OnOffType.OFF, currentState, expectedReply);
}

@Test
public void assertCommandForBrightnessChannelOn() {
HueLightState currentState = new HueLightState();
String expectedReply = "{\"on\" : true}";
String expectedReply = "{\"on\" : true, \"transitiontime\" : 4}";
assertSendCommandForBrightness(OnOffType.ON, currentState, expectedReply);
}

Expand Down
11 changes: 11 additions & 0 deletions addons/binding/org.openhab.binding.hue/ESH-INF/i18n/hue.properties
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,14 @@ offline.light-not-reachable = Hue bridge reports light as not reachable.
offline.sensor-not-reachable = Hue bridge reports sensor as not reachable.
offline.light-removed = Hue bridge reports light as removed.
offline.sensor-removed = Hue bridge reports sensor as removed.

#LightActions
actionLabel=send a light command with a custom fade time
actionDesc=Send a light command with a custom fade time.

actionInputChannelLabel=Channel
actionInputChannelDesc=The channel to send the command to.
actionInputCommandLabel=Command
actionInputCommandDesc=The Command for the light.
actionInputFadeTimeLabel=FadeTime
actionInputFadeTimeDesc=The fade time to use for the light command in ms.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@
<description>The light identifier identifies one certain hue light.</description>
<required>true</required>
</parameter>
<parameter name="fadetime" type="integer" min="0" step="100">
<label>Fade time</label>
<description>Fade time in ms for changing values</description>
<default>400</default>
</parameter>
</config-description>
</thing-type>
</thing:thing-descriptions>
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@
<description>The light identifier identifies one certain hue light.</description>
<required>true</required>
</parameter>
<parameter name="fadetime" type="integer" min="0" step="100">
<label>Fade time</label>
<description>Fade time in ms for changing values</description>
<default>400</default>
</parameter>
</config-description>
</thing-type>
</thing:thing-descriptions>
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@
<description>The light identifier identifies one certain hue light.</description>
<required>true</required>
</parameter>
<parameter name="fadetime" type="integer" min="0" step="100">
<label>Fade time</label>
<description>Fade time in ms for changing values</description>
<default>400</default>
</parameter>
</config-description>
</thing-type>
</thing:thing-descriptions>
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@
<description>The identifier that is used within the hue bridge.</description>
<required>true</required>
</parameter>
<parameter name="fadetime" type="integer" min="0" step="100">
<label>Fade time</label>
<description>Fade time in ms for changing values</description>
<default>400</default>
</parameter>
</config-description>
</thing-type>
</thing:thing-descriptions>
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@
<description>The light identifier identifies one certain hue light.</description>
<required>true</required>
</parameter>
<parameter name="fadetime" type="integer" min="0" step="100">
<label>Fade time</label>
<description>Fade time in ms for changing values</description>
<default>400</default>
</parameter>
</config-description>
</thing-type>
</thing:thing-descriptions>
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Import-Package:
com.google.gson.stream,
javax.measure.quantity,
org.eclipse.jdt.annotation;resolution:=optional,
org.eclipse.smarthome.automation.annotation;resolution:=optional,
org.eclipse.smarthome.config.core,
org.eclipse.smarthome.config.core.status,
org.eclipse.smarthome.config.discovery,
Expand Down
42 changes: 39 additions & 3 deletions addons/binding/org.openhab.binding.hue/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ The following matrix lists the capabilities (channels) for each type:

| Thing type | On/Off | Brightness | Color | Color Temperature |
|-------------|:------:|:----------:|:-----:|:-----------------:|
| 0000 | X | | | |
| 0010 | X | | | |
| 0000 | X | | | |
| 0010 | X | | | |
| 0100 | X | X | | |
| 0110 | X | X | | |
| 0200 | X | | X | |
Expand Down Expand Up @@ -116,6 +116,19 @@ or
0107 motion-sensor [ sensorId="4" ]
```

The following device types also have an optional configuration value to specify the fade time in milliseconds for the transition to a new state:
* Dimmable Light
* Dimmable Plug-in Unit
* Colour Light
* Extended Colour Light
* Colour Temperature Light

| Parameter | Description |
|-----------|-------------------------------------------------------------------------------|
| lightId | Number of the device provided by the Hue bridge. **Mandatory** |
| fadetime | Fade time in Milliseconds to a new state (min="0", step="100", default="400") |


## Channels

The devices support some of the following channels:
Expand Down Expand Up @@ -178,6 +191,29 @@ The `tap_switch_event` can trigger one of the following events:
| Button 3 | Button 3 | 17 |
| Button 4 | Button 4 | 18 |


## Rule Actions

This binding includes a rule action, which allows to change a light channel with a specific fading time from within rules.
There is a separate instance for each light, which can be retrieved e.g. through

```
val hueActions = getActions("hue","hue:0210:00178810d0dc:1")
```

where the first parameter always has to be `hue` and the second is the full Thing UID of the light that should be used.
Once this action instance is retrieved, you can invoke the `fadingLightCommand(String channel, Command command, DecimalType fadeTime)` method on it:

```
hueActions.fadingLightCommand("color", new PercentType(100), new DecimalType(1000))
```

| Parameter | Description |
|-----------|--------------------------------------------------------------------------------------------------|
| channel | The following channels have fade time support: **brightness, color, color_temperature, switch** |
| command | All commands supported by the channel can be used |
| fadeTime | Fade time in Milliseconds to a new light value (min="0", step="100") |

## Full Example

In this example **bulb1** is a standard Philips Hue bulb (LCT001) which supports `color` and `color_temperature`.
Expand All @@ -190,7 +226,7 @@ And there is one Hue Motion Sensor (represented by three devices) and a Hue Dimm
```
Bridge hue:bridge:1 [ ipAddress="192.168.0.64" ] {
0210 bulb1 [ lightId="1" ]
0220 bulb2 [ lightId="2" ]
0220 bulb2 [ lightId="2" fadetime=300 ]
0106 light-level-sensor [ sensorId="3" ]
0107 motion-sensor [ sensorId="4" ]
0302 temperature-sensor [ sensorId="5" ]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
package org.openhab.binding.hue.internal;

import java.lang.reflect.Type;
import java.time.Duration;
import java.util.Map;

import com.google.gson.reflect.TypeToken;
Expand All @@ -30,6 +31,7 @@ public class FullLight extends FullHueObject {
}.getType();

private State state;
private final long fadetime = 400; // milliseconds

FullLight() {
}
Expand All @@ -42,4 +44,8 @@ public class FullLight extends FullHueObject {
public State getState() {
return state;
}

public Duration getFadeTime() {
return Duration.ofMillis(fadetime);
}
}
Loading

0 comments on commit c24244d

Please sign in to comment.