From 694cf3f7143d2b2ffcb1d088ccaea24c96d6fb2e Mon Sep 17 00:00:00 2001 From: Jacob Laursen Date: Sat, 19 Feb 2022 21:48:38 +0100 Subject: [PATCH] [hdpowerview] Add support for setting repeater LED color and brightness (#12308) * Add support for setting repeater LED color and brightness. Fixes #12307 Signed-off-by: Jacob Laursen --- .../org.openhab.binding.hdpowerview/README.md | 7 +++ .../internal/HDPowerViewBindingConstants.java | 2 + .../internal/HDPowerViewWebTargets.java | 18 ++++++ .../hdpowerview/internal/api/Color.java | 57 +++++++++++++++++++ .../internal/api/requests/RepeaterColor.java | 40 +++++++++++++ .../internal/api/responses/RepeaterData.java | 2 + .../handler/HDPowerViewRepeaterHandler.java | 50 ++++++++++++++-- .../OH-INF/i18n/hdpowerview.properties | 2 + .../resources/OH-INF/thing/thing-types.xml | 6 ++ 9 files changed, 180 insertions(+), 4 deletions(-) create mode 100644 bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/Color.java create mode 100644 bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/requests/RepeaterColor.java diff --git a/bundles/org.openhab.binding.hdpowerview/README.md b/bundles/org.openhab.binding.hdpowerview/README.md index 06547b6345af6..d7ef2d2addd7a 100644 --- a/bundles/org.openhab.binding.hdpowerview/README.md +++ b/bundles/org.openhab.binding.hdpowerview/README.md @@ -105,6 +105,8 @@ All of these channels appear in the binding, but only those which have a physica | 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. | @@ -238,6 +240,8 @@ Number Living_Room_Shade_SignalStrength "Living Room Shade Signal Strength" {cha Repeater items: ``` +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"} 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"} ``` @@ -272,6 +276,9 @@ Frame label="Living Room" { Text item=Living_Room_Shade_Battery_Voltage } Frame label="Bedroom" { + Colorpicker item=PowerViewRepeater_Color + Switch item=PowerViewRepeater_Color + Slider item=PowerViewRepeater_Brightness Switch item=Bedroom_Repeater_Identify mappings=[IDENTIFY="Identify"] Switch item=Bedroom_Repeater_BlinkingEnabled } diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/HDPowerViewBindingConstants.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/HDPowerViewBindingConstants.java index b8800f394c159..1b19597dfa770 100644 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/HDPowerViewBindingConstants.java +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/HDPowerViewBindingConstants.java @@ -47,6 +47,8 @@ public class HDPowerViewBindingConstants { public static final String CHANNEL_SHADE_BATTERY_VOLTAGE = "batteryVoltage"; public static final String CHANNEL_SHADE_SIGNAL_STRENGTH = "signalStrength"; + 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"; diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/HDPowerViewWebTargets.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/HDPowerViewWebTargets.java index aa7dd2f3ccc90..654e2f3c60bcf 100644 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/HDPowerViewWebTargets.java +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/HDPowerViewWebTargets.java @@ -26,8 +26,10 @@ import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpStatus; +import org.openhab.binding.hdpowerview.internal.api.Color; import org.openhab.binding.hdpowerview.internal.api.ShadePosition; import org.openhab.binding.hdpowerview.internal.api.requests.RepeaterBlinking; +import org.openhab.binding.hdpowerview.internal.api.requests.RepeaterColor; import org.openhab.binding.hdpowerview.internal.api.requests.ShadeCalibrate; import org.openhab.binding.hdpowerview.internal.api.requests.ShadeJog; import org.openhab.binding.hdpowerview.internal.api.requests.ShadeMove; @@ -510,6 +512,22 @@ public RepeaterData enableRepeaterBlinking(int repeaterId, boolean enable) return repeaterDataFromJson(jsonResponse); } + /** + * Sets color and brightness for a repeater + * + * @param repeaterId id of the repeater for which to set color and brightness + * @return RepeaterData class instance + * @throws HubInvalidResponseException if response is invalid + * @throws HubProcessingException if there is any processing error + * @throws HubMaintenanceException if the hub is down for maintenance + */ + public RepeaterData setRepeaterColor(int repeaterId, Color color) + throws HubInvalidResponseException, HubProcessingException, HubMaintenanceException { + String jsonRequest = gson.toJson(new RepeaterColor(repeaterId, color)); + String jsonResponse = invoke(HttpMethod.PUT, repeaters + repeaterId, null, jsonRequest); + return repeaterDataFromJson(jsonResponse); + } + /** * Invoke a call on the hub server to retrieve information or send a command * diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/Color.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/Color.java new file mode 100644 index 0000000000000..39f1d0f47b24f --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/Color.java @@ -0,0 +1,57 @@ +/** + * Copyright (c) 2010-2022 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.hdpowerview.internal.api; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.core.library.types.HSBType; + +/** + * Color and brightness information for HD PowerView repeater + * + * @author Jacob Laursen - Initial contribution + */ +@NonNullByDefault +public class Color { + public int brightness; + public int red; + public int green; + public int blue; + + public Color(int brightness, HSBType hsbType) { + this.brightness = brightness; + int rgb = hsbType.getRGB(); + java.awt.Color color = new java.awt.Color(rgb); + red = color.getRed(); + green = color.getGreen(); + blue = color.getBlue(); + } + + public Color(int brightness, java.awt.Color color) { + this.brightness = brightness; + red = color.getRed(); + green = color.getGreen(); + blue = color.getBlue(); + } + + public Color(int brightness, int red, int green, int blue) { + this.brightness = brightness; + this.red = red; + this.green = green; + this.blue = blue; + } + + @Override + public String toString() { + return String.format("%d.%d.%d/%d%%", red, green, blue, brightness); + } +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/requests/RepeaterColor.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/requests/RepeaterColor.java new file mode 100644 index 0000000000000..960e95f5878c9 --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/requests/RepeaterColor.java @@ -0,0 +1,40 @@ +/** + * Copyright (c) 2010-2022 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.hdpowerview.internal.api.requests; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.binding.hdpowerview.internal.api.Color; + +/** + * Color state of a single Repeater for being updated by an HD PowerView Hub + * + * @author Jacob Laursen - Initial contribution + */ +@NonNullByDefault +public class RepeaterColor { + public Repeater repeater; + + public class Repeater { + public int id; + public Color color; + + public Repeater(int id, Color color) { + this.id = id; + this.color = color; + } + } + + public RepeaterColor(int id, Color color) { + repeater = new Repeater(id, color); + } +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/RepeaterData.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/RepeaterData.java index 8b0c255309ec3..a083f91a35a76 100644 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/RepeaterData.java +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/RepeaterData.java @@ -16,6 +16,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; +import org.openhab.binding.hdpowerview.internal.api.Color; import org.openhab.binding.hdpowerview.internal.api.Firmware; /** @@ -31,6 +32,7 @@ public class RepeaterData { public int groupId; public boolean blinkEnabled; public @Nullable Firmware firmware; + public @Nullable Color color; public String getName() { return new String(Base64.getDecoder().decode(name)); diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewRepeaterHandler.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewRepeaterHandler.java index 26b465ed99440..1274ff1faa597 100644 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewRepeaterHandler.java +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewRepeaterHandler.java @@ -20,13 +20,16 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.openhab.binding.hdpowerview.internal.HDPowerViewWebTargets; +import org.openhab.binding.hdpowerview.internal.api.Color; import org.openhab.binding.hdpowerview.internal.api.Firmware; import org.openhab.binding.hdpowerview.internal.api.responses.RepeaterData; import org.openhab.binding.hdpowerview.internal.config.HDPowerViewRepeaterConfiguration; import org.openhab.binding.hdpowerview.internal.exceptions.HubException; 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.OnOffType; +import org.openhab.core.library.types.PercentType; import org.openhab.core.library.types.StringType; import org.openhab.core.thing.Bridge; import org.openhab.core.thing.ChannelUID; @@ -112,11 +115,43 @@ public void handleCommand(ChannelUID channelUID, Command command) { RepeaterData repeaterData; switch (channelUID.getId()) { + case CHANNEL_REPEATER_COLOR: + if (command instanceof HSBType) { + Color currentColor = webTargets.getRepeater(repeaterId).color; + if (currentColor != null) { + HSBType hsbCommand = (HSBType) command; + var color = new Color(currentColor.brightness, 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) { + Color currentColor = webTargets.getRepeater(repeaterId).color; + if (currentColor != null) { + PercentType brightness = (PercentType) command; + var color = new Color(brightness.intValue(), currentColor.red, currentColor.green, + currentColor.blue); + repeaterData = webTargets.setRepeaterColor(repeaterId, color); + scheduler.submit(() -> updatePropertyAndStates(repeaterData)); + } + } + break; case CHANNEL_REPEATER_IDENTIFY: if (command instanceof StringType) { if (COMMAND_IDENTIFY.equals(((StringType) command).toString())) { repeaterData = webTargets.identifyRepeater(repeaterId); - scheduler.submit(() -> updatePropertyAndState(repeaterData)); + scheduler.submit(() -> updatePropertyAndStates(repeaterData)); cancelResetIdentifyStateJob(); resetIdentifyStateFuture = scheduler.schedule(() -> { updateState(CHANNEL_REPEATER_IDENTIFY, UnDefType.UNDEF); @@ -129,7 +164,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { break; case CHANNEL_REPEATER_BLINKING_ENABLED: repeaterData = webTargets.enableRepeaterBlinking(repeaterId, OnOffType.ON == command); - scheduler.submit(() -> updatePropertyAndState(repeaterData)); + scheduler.submit(() -> updatePropertyAndStates(repeaterData)); break; } } catch (HubInvalidResponseException e) { @@ -185,7 +220,7 @@ private synchronized void poll() { logger.debug("Polling for status information"); RepeaterData repeaterData = webTargets.getRepeater(repeaterId); - updatePropertyAndState(repeaterData); + updatePropertyAndStates(repeaterData); } catch (HubInvalidResponseException e) { Throwable cause = e.getCause(); @@ -201,7 +236,7 @@ private synchronized void poll() { } } - private void updatePropertyAndState(RepeaterData repeaterData) { + private void updatePropertyAndStates(RepeaterData repeaterData) { updateStatus(ThingStatus.ONLINE); Firmware firmware = repeaterData.firmware; @@ -212,6 +247,13 @@ private void updatePropertyAndState(RepeaterData repeaterData) { logger.warn("Repeater firmware version missing in response"); } + 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)); + } + updateState(CHANNEL_REPEATER_BLINKING_ENABLED, repeaterData.blinkEnabled ? OnOffType.ON : OnOffType.OFF); } } diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/resources/OH-INF/i18n/hdpowerview.properties b/bundles/org.openhab.binding.hdpowerview/src/main/resources/OH-INF/i18n/hdpowerview.properties index d09d2fd988953..e72a760ba8208 100644 --- a/bundles/org.openhab.binding.hdpowerview/src/main/resources/OH-INF/i18n/hdpowerview.properties +++ b/bundles/org.openhab.binding.hdpowerview/src/main/resources/OH-INF/i18n/hdpowerview.properties @@ -7,6 +7,8 @@ binding.hdpowerview.description = The Hunter Douglas PowerView binding provides thing-type.hdpowerview.hub.label = PowerView Hub thing-type.hdpowerview.hub.description = Hunter Douglas (Luxaflex) PowerView Hub +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.label = PowerView Repeater thing-type.hdpowerview.repeater.description = Hunter Douglas (Luxaflex) PowerView Repeater thing-type.hdpowerview.shade.label = PowerView Shade diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.hdpowerview/src/main/resources/OH-INF/thing/thing-types.xml index a0c845f803a73..95aaca7fc56d7 100644 --- a/bundles/org.openhab.binding.hdpowerview/src/main/resources/OH-INF/thing/thing-types.xml +++ b/bundles/org.openhab.binding.hdpowerview/src/main/resources/OH-INF/thing/thing-types.xml @@ -90,6 +90,12 @@ Hunter Douglas (Luxaflex) PowerView Repeater + + Controls the color of the LED ring + + + Controls the brightness of the LED ring +