Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[hdpowerview] Improve color channel for Repeater and remove redundant brightness channel #15880

Merged
merged 2 commits into from
Nov 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions bundles/org.openhab.binding.hdpowerview/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,12 +129,13 @@ On Generation 3 gateways the signal strength is displayed in dBm (deciBel-milliW

### Channels for Repeaters (Thing type `repeater`)<sup>[1/2]</sup>

| Channel | Item Type | Description |
|-----------------|-----------|---------------------------------------------------------------------------------------------|
| color | Color | Controls the color of the LED ring. A switch item can be linked: ON = white, OFF = turn off |
| brightness | Dimmer | Controls the brightness of the LED ring. |
| identify | String | Flash repeater to identify. Valid values are: `IDENTIFY` |
| blinkingEnabled | Switch | Blink during commands. |
| Channel | Item Type | Description |
|-----------------|-----------|----------------------------------------------------------|
| color | Color | Controls the color of the LED ring. |
| color | Dimmer | Controls the brightness of the LED ring. |
| color | Switch | Switches the LED ring on or off. |
| identify | String | Flash repeater to identify. Valid values are: `IDENTIFY` |
| blinkingEnabled | Switch | Blink during commands. |

### Roller Shutter Up/Down Position vs. Open/Close State

Expand Down Expand Up @@ -292,7 +293,7 @@ Repeater items<sup>[1/2]</sup>:

```java
Color Bedroom_Repeater_Color "Bedroom Repeater Color" {channel="hdpowerview:repeater:home:r16384:color"}
Dimmer Bedroom_Repeater_Brightness "Bedroom Repeater Brightness" {channel="hdpowerview:repeater:home:r16384:brightness"}
Dimmer Bedroom_Repeater_Brightness "Bedroom Repeater Brightness" {channel="hdpowerview:repeater:home:r16384:color"}
String Bedroom_Repeater_Identify "Bedroom Repeater Identify" {channel="hdpowerview:repeater:home:r16384:identify"}
Switch Bedroom_Repeater_BlinkingEnabled "Bedroom Repeater Blinking Enabled [%s]" {channel="hdpowerview:repeater:home:r16384:blinkingEnabled"}
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ public class HDPowerViewBindingConstants {
public static final String CHANNEL_SHADE_REPEATER_RSSI = "repeaterRssi";

public static final String CHANNEL_REPEATER_COLOR = "color";
public static final String CHANNEL_REPEATER_BRIGHTNESS = "brightness";
public static final String CHANNEL_REPEATER_IDENTIFY = "identify";
public static final String CHANNEL_REPEATER_BLINKING_ENABLED = "blinkingEnabled";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,21 @@ public Color(int brightness, java.awt.Color color) {
this(brightness, color.getRed(), color.getGreen(), color.getBlue());
}

public Color(int brightness, Color color) {
this(brightness, color.red, color.green, color.blue);
}

public Color(int brightness, int red, int green, int blue) {
this.brightness = brightness;
this.red = red;
this.green = green;
this.blue = blue;
}

public boolean isBlack() {
return red == 0 && green == 0 && blue == 0;
}

@Override
public String toString() {
return String.format("%d.%d.%d/%d%%", red, green, blue, brightness);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.openhab.binding.hdpowerview.internal.exceptions.HubInvalidResponseException;
import org.openhab.binding.hdpowerview.internal.exceptions.HubMaintenanceException;
import org.openhab.core.library.types.HSBType;
import org.openhab.core.library.types.IncreaseDecreaseType;
import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.PercentType;
import org.openhab.core.library.types.StringType;
Expand All @@ -37,6 +38,7 @@
import org.openhab.core.thing.ThingStatus;
import org.openhab.core.thing.ThingStatusDetail;
import org.openhab.core.types.Command;
import org.openhab.core.types.RefreshType;
import org.openhab.core.types.UnDefType;
import org.openhab.core.util.ColorUtil;
import org.slf4j.Logger;
Expand All @@ -54,6 +56,7 @@ public class HDPowerViewRepeaterHandler extends AbstractHubbedThingHandler {

private static final int REFRESH_INTERVAL_MINUTES = 5;
private static final int IDENTITY_PERIOD_SECONDS = 3;
private static final int BRIGHTNESS_STEP_PERCENT = 5;
private static final String COMMAND_IDENTIFY = "IDENTIFY";

private @Nullable ScheduledFuture<?> refreshStatusFuture = null;
Expand Down Expand Up @@ -94,40 +97,17 @@ public void handleCommand(ChannelUID channelUID, Command command) {
logger.warn("Missing bridge handler");
return;
}
if (command == RefreshType.REFRESH) {
scheduleRefreshJob();
return;
}
HDPowerViewWebTargets webTargets = bridge.getWebTargets();
try {
RepeaterData repeaterData;

switch (channelUID.getId()) {
case CHANNEL_REPEATER_COLOR:
if (command instanceof HSBType hsbCommand) {
Color currentColor = webTargets.getRepeater(repeaterId).color;
if (currentColor != null) {
var color = new Color(currentColor.brightness, ColorUtil.hsbTosRgb(hsbCommand));
repeaterData = webTargets.setRepeaterColor(repeaterId, color);
scheduler.submit(() -> updatePropertyAndStates(repeaterData));
}
} else if (command instanceof OnOffType) {
Color currentColor = webTargets.getRepeater(repeaterId).color;
if (currentColor != null) {
var color = command == OnOffType.ON
? new Color(currentColor.brightness, java.awt.Color.WHITE)
: new Color(currentColor.brightness, java.awt.Color.BLACK);
repeaterData = webTargets.setRepeaterColor(repeaterId, color);
scheduler.submit(() -> updatePropertyAndStates(repeaterData));
}
}
break;
case CHANNEL_REPEATER_BRIGHTNESS:
if (command instanceof PercentType brightnessCommand) {
Color currentColor = webTargets.getRepeater(repeaterId).color;
if (currentColor != null) {
var color = new Color(brightnessCommand.intValue(), currentColor.red, currentColor.green,
currentColor.blue);
repeaterData = webTargets.setRepeaterColor(repeaterId, color);
scheduler.submit(() -> updatePropertyAndStates(repeaterData));
}
}
handleColorCommand(command, webTargets);
break;
case CHANNEL_REPEATER_IDENTIFY:
if (command instanceof StringType stringCommand) {
Expand Down Expand Up @@ -163,6 +143,54 @@ public void handleCommand(ChannelUID channelUID, Command command) {
}
}

private void handleColorCommand(Command command, HDPowerViewWebTargets webTargets) throws HubException {
if (command instanceof HSBType hsbCommand) {
var color = new Color(hsbCommand.getBrightness().intValue(), ColorUtil.hsbTosRgb(hsbCommand));
RepeaterData repeaterData = webTargets.setRepeaterColor(repeaterId, color);
scheduler.submit(() -> updatePropertyAndStates(repeaterData));
return;
}
Color currentColor = webTargets.getRepeater(repeaterId).color;
if (currentColor == null) {
return;
}
Color newColor;
if (command instanceof PercentType brightnessCommand) {
newColor = applyBrightnessToColor(currentColor, brightnessCommand.intValue());
} else if (command instanceof IncreaseDecreaseType increaseDecreaseCommand) {
int brightness = switch (increaseDecreaseCommand) {
case INCREASE -> currentColor.brightness + BRIGHTNESS_STEP_PERCENT;
case DECREASE -> currentColor.brightness - BRIGHTNESS_STEP_PERCENT;
};
brightness = brightness < 0 ? 0 : brightness > 100 ? 100 : brightness;
newColor = applyBrightnessToColor(currentColor, brightness);
} else if (command instanceof OnOffType) {
// Light is turned off either by RGB black or zero brightness.
int brightness;
if (command == OnOffType.ON) {
// Turn on with maximum brightness level per default,
// if no existing brightness level is available.
brightness = currentColor.brightness > 0 ? currentColor.brightness : 100;
} else {
// Turn off by zero brightness to preserve color.
brightness = 0;
}
newColor = applyBrightnessToColor(currentColor, brightness);
} else {
logger.warn("Unsupported command: {}", command);
return;
}
RepeaterData repeaterData = webTargets.setRepeaterColor(repeaterId, newColor);
scheduler.submit(() -> updatePropertyAndStates(repeaterData));
}

private Color applyBrightnessToColor(Color currentColor, int brightness) {
// If light is off by RGB black, then reset to white since otherwise brightness
// would have no effect; otherwise preserve color.
return currentColor.isBlack() ? new Color(brightness, java.awt.Color.WHITE)
: new Color(brightness, currentColor);
}

private void cancelResetIdentifyStateJob() {
ScheduledFuture<?> scheduledJob = resetIdentifyStateFuture;
if (scheduledJob != null) {
Expand All @@ -182,7 +210,7 @@ private void scheduleRefreshJob() {
private void cancelRefreshJob() {
ScheduledFuture<?> future = this.refreshStatusFuture;
if (future != null) {
future.cancel(false);
future.cancel(true);
}
this.refreshStatusFuture = null;
}
Expand Down Expand Up @@ -228,10 +256,17 @@ private void updatePropertyAndStates(RepeaterData repeaterData) {
Color color = repeaterData.color;
if (color != null) {
logger.debug("Repeater color data received: {}", color.toString());
updateState(CHANNEL_REPEATER_COLOR, HSBType.fromRGB(color.red, color.green, color.red));
updateState(CHANNEL_REPEATER_BRIGHTNESS, new PercentType(color.brightness));
HSBType hsb;
if (color.isBlack()) {
// Light is off when RGB black, so discard brightness as otherwise it would appear on.
hsb = HSBType.BLACK;
} else {
hsb = HSBType.fromRGB(color.red, color.green, color.red);
hsb = new HSBType(hsb.getHue(), hsb.getSaturation(), new PercentType(color.brightness));
}
updateState(CHANNEL_REPEATER_COLOR, hsb);
}

updateState(CHANNEL_REPEATER_BLINKING_ENABLED, repeaterData.blinkEnabled ? OnOffType.ON : OnOffType.OFF);
updateState(CHANNEL_REPEATER_BLINKING_ENABLED, OnOffType.from(repeaterData.blinkEnabled));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ thing-type.hdpowerview.hub.label = PowerView Hub
thing-type.hdpowerview.hub.description = Hunter Douglas (Luxaflex) PowerView Hub
thing-type.hdpowerview.repeater.label = PowerView Repeater
thing-type.hdpowerview.repeater.description = Hunter Douglas (Luxaflex) PowerView Repeater
thing-type.hdpowerview.repeater.channel.brightness.description = Controls the brightness of the LED ring
thing-type.hdpowerview.repeater.channel.color.description = Controls the color of the LED ring
thing-type.hdpowerview.repeater.channel.color.description = Controls the color and brightness of the LED ring
thing-type.hdpowerview.shade.label = PowerView Shade
thing-type.hdpowerview.shade.description = Hunter Douglas (Luxaflex) PowerView Gen 1/2 Shade
thing-type.hdpowerview.shade.channel.hubRssi.label = Hub RSSI
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,14 @@

<channels>
<channel id="color" typeId="system.color">
<description>Controls the color of the LED ring</description>
</channel>
<channel id="brightness" typeId="system.brightness">
<description>Controls the brightness of the LED ring</description>
<description>Controls the color and brightness of the LED ring</description>
</channel>
<channel id="identify" typeId="repeater-identify"/>
<channel id="blinkingEnabled" typeId="repeater-blinking-enabled"/>
</channels>

<properties>
<property name="thingTypeVersion">1</property>
<property name="vendor">Hunter Douglas (Luxaflex)</property>
<property name="modelId">PowerView Repeater</property>
</properties>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,9 @@
xmlns:update="https://openhab.org/schemas/update-description/v1.0.0"
xsi:schemaLocation="https://openhab.org/schemas/update-description/v1.0.0 https://openhab.org/schemas/update-description-1.0.0.xsd">

<thing-type uid="powerview:shade">
<thing-type uid="hdpowerview:repeater">
<instruction-set targetVersion="1">
<update-channel id="position">
<type>powerview:shade-position</type>
</update-channel>
<update-channel id="secondary">
<type>powerview:shade-position</type>
<label>Secondary Position</label>
<description>The secondary vertical position (on top-down/bottom-up shades)</description>
</update-channel>
<update-channel id="vane">
<type>powerview:shade-vane</type>
</update-channel>
<remove-channel id="brightness"/>
</instruction-set>
</thing-type>

Expand Down