From: Jacob Laursen Date: Fri, 4 Nov 2022 17:24:39 +0000 (+0100) Subject: [hdpowerview] Restructure DTO classes (#13630) X-Git-Url: https://git.basschouten.com/?a=commitdiff_plain;h=c114714a7b21b0eeef60f75a3377ec2bc2310624;p=openhab-addons.git [hdpowerview] Restructure DTO classes (#13630) * Extract nested DTO's to separate classes * Rename api to dto * Move test classes into internal * Finish moving of files and fix namespaces Signed-off-by: Jacob Laursen --- 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 f8ba04c153..aa3525e7d9 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 @@ -27,32 +27,32 @@ import org.eclipse.jetty.client.util.StringContentProvider; 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.HubFirmware; -import org.openhab.binding.hdpowerview.internal.api.ShadePosition; -import org.openhab.binding.hdpowerview.internal.api.SurveyData; -import org.openhab.binding.hdpowerview.internal.api.UserData; -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; -import org.openhab.binding.hdpowerview.internal.api.requests.ShadeStop; -import org.openhab.binding.hdpowerview.internal.api.responses.FirmwareVersion; -import org.openhab.binding.hdpowerview.internal.api.responses.Repeater; -import org.openhab.binding.hdpowerview.internal.api.responses.RepeaterData; -import org.openhab.binding.hdpowerview.internal.api.responses.Repeaters; -import org.openhab.binding.hdpowerview.internal.api.responses.SceneCollections; -import org.openhab.binding.hdpowerview.internal.api.responses.SceneCollections.SceneCollection; -import org.openhab.binding.hdpowerview.internal.api.responses.Scenes; -import org.openhab.binding.hdpowerview.internal.api.responses.Scenes.Scene; -import org.openhab.binding.hdpowerview.internal.api.responses.ScheduledEvents; -import org.openhab.binding.hdpowerview.internal.api.responses.ScheduledEvents.ScheduledEvent; -import org.openhab.binding.hdpowerview.internal.api.responses.Shade; -import org.openhab.binding.hdpowerview.internal.api.responses.Shades; -import org.openhab.binding.hdpowerview.internal.api.responses.Shades.ShadeData; -import org.openhab.binding.hdpowerview.internal.api.responses.Survey; -import org.openhab.binding.hdpowerview.internal.api.responses.UserDataResponse; +import org.openhab.binding.hdpowerview.internal.dto.Color; +import org.openhab.binding.hdpowerview.internal.dto.HubFirmware; +import org.openhab.binding.hdpowerview.internal.dto.Scene; +import org.openhab.binding.hdpowerview.internal.dto.SceneCollection; +import org.openhab.binding.hdpowerview.internal.dto.ScheduledEvent; +import org.openhab.binding.hdpowerview.internal.dto.ShadeData; +import org.openhab.binding.hdpowerview.internal.dto.ShadePosition; +import org.openhab.binding.hdpowerview.internal.dto.SurveyData; +import org.openhab.binding.hdpowerview.internal.dto.UserData; +import org.openhab.binding.hdpowerview.internal.dto.requests.RepeaterBlinking; +import org.openhab.binding.hdpowerview.internal.dto.requests.RepeaterColor; +import org.openhab.binding.hdpowerview.internal.dto.requests.ShadeCalibrate; +import org.openhab.binding.hdpowerview.internal.dto.requests.ShadeJog; +import org.openhab.binding.hdpowerview.internal.dto.requests.ShadeMove; +import org.openhab.binding.hdpowerview.internal.dto.requests.ShadeStop; +import org.openhab.binding.hdpowerview.internal.dto.responses.FirmwareVersion; +import org.openhab.binding.hdpowerview.internal.dto.responses.Repeater; +import org.openhab.binding.hdpowerview.internal.dto.responses.RepeaterData; +import org.openhab.binding.hdpowerview.internal.dto.responses.Repeaters; +import org.openhab.binding.hdpowerview.internal.dto.responses.SceneCollections; +import org.openhab.binding.hdpowerview.internal.dto.responses.Scenes; +import org.openhab.binding.hdpowerview.internal.dto.responses.ScheduledEvents; +import org.openhab.binding.hdpowerview.internal.dto.responses.Shade; +import org.openhab.binding.hdpowerview.internal.dto.responses.Shades; +import org.openhab.binding.hdpowerview.internal.dto.responses.Survey; +import org.openhab.binding.hdpowerview.internal.dto.responses.UserDataResponse; import org.openhab.binding.hdpowerview.internal.exceptions.HubInvalidResponseException; import org.openhab.binding.hdpowerview.internal.exceptions.HubMaintenanceException; import org.openhab.binding.hdpowerview.internal.exceptions.HubProcessingException; diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/BatteryKind.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/BatteryKind.java deleted file mode 100644 index 229d0abce3..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/BatteryKind.java +++ /dev/null @@ -1,57 +0,0 @@ -/** - * 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.eclipse.jdt.annotation.Nullable; - -/** - * An enum for the type of power supply in a shade. - * - * @author Andrew Fiddian-Green - Initial contribution - */ -@NonNullByDefault -public enum BatteryKind { - ERROR_UNKNOWN(-1), - HARDWIRED_POWER_SUPPLY(1), - BATTERY_WAND(2), - RECHARGEABLE_BATTERY_WAND(3); - - private int batteryKind; - - private BatteryKind(int i) { - this.batteryKind = i; - } - - /** - * Determine the BatteryKind by parsing the given string value. - * - * @param value the string to parse, or null. - * @return the BatteryKind or ERROR_UNKNOWN in case of error. - */ - public static BatteryKind fromString(@Nullable String value) { - if (value != null) { - try { - int intValue = Integer.parseInt(value); - for (BatteryKind e : values()) { - if (e.batteryKind == intValue) { - return e; - } - } - } catch (NumberFormatException e) { - // fall through - } - } - return ERROR_UNKNOWN; - } -} 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 deleted file mode 100644 index 39f1d0f47b..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/Color.java +++ /dev/null @@ -1,57 +0,0 @@ -/** - * 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/CoordinateSystem.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/CoordinateSystem.java deleted file mode 100644 index 236e468947..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/CoordinateSystem.java +++ /dev/null @@ -1,111 +0,0 @@ -/** - * 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.eclipse.jdt.annotation.Nullable; - -/** - * Shade coordinate system (a.k.a. position kind), as returned by the HD PowerView hub. - * - * @param NONE a coordinate system that does not refer to any type of physical rail. - * @param PRIMARY_POSITION primary rail, whose coordinate value 0 means shade is closed. - * @param SECONDARY_POSITION secondary rail, whose coordinate value 0 means shade is open. - * @param VANE_TILT_POSITION vane/tilt operator, whose coordinate system is for vanes. - * @param ERROR_UNKNOWN unsupported coordinate system. - * - * @author Andy Lintner - Initial contribution of the original enum called - * ShadePositionKind - * - * @author Andrew Fiddian-Green - Rewritten as a new enum called - * CoordinateSystem to support secondary rail positions and be more - * explicit on coordinate directions and ranges - */ -@NonNullByDefault -public enum CoordinateSystem { - /*- - * Specifies the coordinate system used for the position of the shade. Top-down - * shades are in the same coordinate space as bottom-up shades. Shade position - * values for top-down shades would be reversed for bottom-up shades. For - * example, since 65535 is the open value for a bottom-up shade, it is the - * closed value for a top-down shade. The top-down/bottom-up shade is different - * in that instead of the top and bottom rail operating in one coordinate space - * like the top-down and the bottom-up, it operates in two where the top - * (middle) rail closed value is 0 and the bottom (primary) rail closed position - * is also 0 and fully open for both is 65535 - * - * The position element can take on multiple states depending on the family of - * shade under control. - * - * The ranges of position integer values are - * shades: 0..65535 - * vanes: 0..32767 - * - * Shade fully up: (top-down: open, bottom-up: closed) - * posKind: 1 {ZERO_IS_CLOSED} - * position: 65535 - * - * Shade and vane fully down: (top-down: closed, bottom-up: open) - * posKind: 1 {ZERO_IS_CLOSED} - * position1: 0 - * - * ALTERNATE: Shade and vane fully down: (top-down: closed, bottom-up: open) - * posKind: 3 {VANE_COORDS} - * position: 0 - * - * Shade fully down (closed) and vane fully up (open): - * posKind: 3 {VANE_COORDS} - * position: 32767 - * - * Dual action, secondary top-down shade fully up (closed): - * posKind: 2 {ZERO_IS_OPEN} - * position: 0 - * - * Dual action, secondary top-down shade fully down (open): - * posKind: 2 {ZERO_IS_OPEN} - * position: 65535 - * - */ - NONE, - PRIMARY_POSITION, - SECONDARY_POSITION, - VANE_TILT_POSITION, - ERROR_UNKNOWN; - - public static final int MAX_SHADE = 65535; - public static final int MAX_VANE = 32767; - - /** - * Converts an HD PowerView posKind integer value to a CoordinateSystem enum value. - * - * @param posKind input integer value. - * @return corresponding CoordinateSystem enum. - */ - public static CoordinateSystem fromPosKind(int posKind) { - try { - return CoordinateSystem.values()[posKind]; - } catch (ArrayIndexOutOfBoundsException e) { - return ERROR_UNKNOWN; - } - } - - /** - * Check if the coordinate system matches the given posKind. - * - * @param posKind - * @return true if equal. - */ - public boolean equals(@Nullable Integer posKind) { - return (posKind != null) && (posKind.intValue() == ordinal()); - } -} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/Firmware.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/Firmware.java deleted file mode 100644 index fd627c8b9b..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/Firmware.java +++ /dev/null @@ -1,35 +0,0 @@ -/** - * 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.eclipse.jdt.annotation.Nullable; - -/** - * Firmware version information for HD PowerView components - * - * @author Jacob Laursen - Initial contribution - */ -@NonNullByDefault -public class Firmware { - @Nullable - public String name; - public int revision; - public int subRevision; - public int build; - - @Override - public String toString() { - return String.format("%d.%d.%d", revision, subRevision, build); - } -} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/HubFirmware.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/HubFirmware.java deleted file mode 100644 index 0a625b2f16..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/HubFirmware.java +++ /dev/null @@ -1,29 +0,0 @@ -/** - * 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.eclipse.jdt.annotation.Nullable; - -/** - * Firmware information for an HD PowerView hub - * - * @author Jacob Laursen - Initial contribution - */ -@NonNullByDefault -public class HubFirmware { - @Nullable - public Firmware mainProcessor; - @Nullable - public Firmware radio; -} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/ShadePosition.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/ShadePosition.java deleted file mode 100644 index 0eee7aff49..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/ShadePosition.java +++ /dev/null @@ -1,381 +0,0 @@ -/** - * 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 static org.openhab.binding.hdpowerview.internal.api.CoordinateSystem.*; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; -import org.openhab.binding.hdpowerview.internal.database.ShadeCapabilitiesDatabase.Capabilities; -import org.openhab.core.library.types.PercentType; -import org.openhab.core.types.State; -import org.openhab.core.types.UnDefType; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * The position of a single shade, as returned by the HD PowerView hub - * - * @author Andy Lintner - Initial contribution - * @author Andrew Fiddian-Green - Added support for secondary rail positions - */ -@NonNullByDefault -public class ShadePosition { - - private final transient Logger logger = LoggerFactory.getLogger(ShadePosition.class); - - /** - * Primary actuator position. - */ - private int posKind1; - private int position1; - - /** - * Secondary actuator position. - * - * Here we have to use Integer objects rather than just int primitives because these are secondary optional position - * elements in the JSON payload, so the GSON de-serializer might leave them as null. - */ - private @Nullable Integer posKind2 = null; - private @Nullable Integer position2 = null; - - public ShadePosition() { - } - - /** - * Get the shade's State for the given actuator class resp. coordinate system. - * - * @param shadeCapabilities the shade Thing capabilities. - * @param posKindCoords the actuator class (coordinate system) whose state is to be returned. - * @return the current state. - */ - public State getState(Capabilities shadeCapabilities, CoordinateSystem posKindCoords) { - State result = getPosition1(shadeCapabilities, posKindCoords); - if (result == UnDefType.UNDEF) { - result = getPosition2(shadeCapabilities, posKindCoords); - } - logger.trace("getState(): capabilities={}, coords={} => result={}", shadeCapabilities, posKindCoords, result); - return result; - } - - /** - * Set the shade's position1 value for the given actuator class resp. coordinate system. - * - * @param shadeCapabilities the shade Thing capabilities. - * @param posKindCoords the actuator class (coordinate system) whose state is to be changed. - * @param percent the new position value. - */ - private void setPosition1(Capabilities shadeCapabilities, CoordinateSystem posKindCoords, int percent) { - switch (posKindCoords) { - case PRIMARY_POSITION: - /* - * Primary rail of a bottom-up shade, or lower rail of a dual action shade: => INVERTED - */ - if (shadeCapabilities.supportsPrimary() && shadeCapabilities.supportsSecondary()) { - // on dual rail shades constrain percent to not move the lower rail above the upper - State secondary = getState(shadeCapabilities, SECONDARY_POSITION); - if (secondary instanceof PercentType) { - int secPercent = ((PercentType) secondary).intValue(); - if (percent < secPercent) { - percent = secPercent; - } - } - } - posKind1 = posKindCoords.ordinal(); - position1 = MAX_SHADE - (int) Math.round((double) percent / 100 * MAX_SHADE); - break; - - case SECONDARY_POSITION: - /* - * Secondary, blackout shade a 'Duolite' shade: => INVERTED - * Secondary, upper rail of a dual action shade: => NOT INVERTED - */ - posKind1 = posKindCoords.ordinal(); - if (shadeCapabilities.supportsSecondaryOverlapped()) { - position1 = MAX_SHADE - (int) Math.round((double) percent / 100 * MAX_SHADE); - } else { - position1 = (int) Math.round((double) percent / 100 * MAX_SHADE); - } - break; - - case VANE_TILT_POSITION: - /* - * Vane angle of the primary rail of a bottom-up single action shade: => NOT INVERTED - */ - posKind1 = posKindCoords.ordinal(); - int max = shadeCapabilities.supportsTilt180() ? MAX_SHADE : MAX_VANE; - position1 = (int) Math.round((double) percent / 100 * max); - break; - - default: - posKind1 = CoordinateSystem.NONE.ordinal(); - position1 = 0; - } - } - - /** - * Get the shade's position1 State for the given actuator class resp. coordinate system. - * - * @param shadeCapabilities the shade Thing capabilities. - * @param posKindCoords the actuator class (coordinate system) whose state is to be returned. - * @return the State (or UNDEF if not available). - */ - private State getPosition1(Capabilities shadeCapabilities, CoordinateSystem posKindCoords) { - switch (posKindCoords) { - case PRIMARY_POSITION: - /* - * Primary rail of a bottom-up shade, or lower rail of a dual action shade: => INVERTED - */ - if (posKindCoords.equals(posKind1)) { - return new PercentType(100 - (int) Math.round((double) position1 / MAX_SHADE * 100)); - } - if (VANE_TILT_POSITION.equals(posKind1) && shadeCapabilities.supportsTiltOnClosed()) { - return PercentType.HUNDRED; - } - if (SECONDARY_POSITION.equals(posKind1) && shadeCapabilities.supportsSecondaryOverlapped()) { - return PercentType.HUNDRED; - } - break; - - case SECONDARY_POSITION: - /* - * Secondary, blackout shade a 'Duolite' shade: => INVERTED - * Secondary, upper rail of a dual action shade: => NOT INVERTED - */ - if (posKindCoords.equals(posKind1)) { - if (shadeCapabilities.supportsSecondaryOverlapped()) { - return new PercentType(100 - (int) Math.round((double) position1 / MAX_SHADE * 100)); - } - return new PercentType((int) Math.round((double) position1 / MAX_SHADE * 100)); - } - if (!SECONDARY_POSITION.equals(posKind1) && shadeCapabilities.supportsSecondaryOverlapped()) { - return PercentType.ZERO; - } - break; - - case VANE_TILT_POSITION: - /* - * Vane angle of the primary rail of a bottom-up single action shade: => NOT INVERTED - * - * If the shades are not open, the vane position is undefined; if the the shades - * are exactly open then the vanes are at zero; otherwise return the actual vane - * position itself - * - * note: sometimes the hub may return a value of position1 > MAX_VANE (seems to - * be a bug in the hub) so we avoid an out of range exception via the Math.min() - * function below.. - */ - if (posKindCoords.equals(posKind1)) { - int max = shadeCapabilities.supportsTilt180() ? MAX_SHADE : MAX_VANE; - return new PercentType((int) Math.round((double) Math.min(position1, max) / max * 100)); - } - if (PRIMARY_POSITION.equals(posKind1) && shadeCapabilities.supportsTiltOnClosed()) { - return position1 != 0 ? UnDefType.UNDEF : PercentType.ZERO; - } - if (SECONDARY_POSITION.equals(posKind1) && shadeCapabilities.supportsSecondaryOverlapped() - && shadeCapabilities.supportsTiltOnClosed()) { - return PercentType.HUNDRED; - } - break; - - case ERROR_UNKNOWN: - case NONE: - // fall through, return UNDEF - } - return UnDefType.UNDEF; - } - - /** - * Set the shade's position2 value for the given actuator class resp. coordinate system. - * - * @param shadeCapabilities the shade Thing capabilities. - * @param posKindCoords the actuator class (coordinate system) whose state is to be changed. - * @param percent the new position value. - */ - private void setPosition2(Capabilities shadeCapabilities, CoordinateSystem posKindCoords, int percent) { - switch (posKindCoords) { - case PRIMARY_POSITION: - /* - * Primary rail of a bottom-up shade, or lower rail of a dual action shade: => INVERTED - */ - posKind2 = posKindCoords.ordinal(); - position2 = Integer.valueOf(MAX_SHADE - (int) Math.round((double) percent / 100 * MAX_SHADE)); - break; - - case SECONDARY_POSITION: - /* - * Secondary, upper rail of a dual action shade: => NOT INVERTED - */ - if (shadeCapabilities.supportsPrimary() && shadeCapabilities.supportsSecondary()) { - // on dual rail shades constrain percent to not move the upper rail below the lower - State primary = getState(shadeCapabilities, PRIMARY_POSITION); - if (primary instanceof PercentType) { - int primaryPercent = ((PercentType) primary).intValue(); - if (percent > primaryPercent) { - percent = primaryPercent; - } - } - } - posKind2 = posKindCoords.ordinal(); - position2 = Integer.valueOf((int) Math.round((double) percent / 100 * MAX_SHADE)); - break; - - case VANE_TILT_POSITION: - posKind2 = posKindCoords.ordinal(); - int max = shadeCapabilities.supportsTilt180() ? MAX_SHADE : MAX_VANE; - position2 = Integer.valueOf((int) Math.round((double) percent / 100 * max)); - break; - - default: - posKind2 = null; - position2 = null; - } - } - - /** - * Get the shade's position2 State for the given actuator class resp. coordinate system. - * - * @param shadeCapabilities the shade Thing capabilities. - * @param posKindCoords the actuator class (coordinate system) whose state is to be returned. - * @return the State (or UNDEF if not available). - */ - private State getPosition2(Capabilities shadeCapabilities, CoordinateSystem posKindCoords) { - Integer posKind2 = this.posKind2; - Integer position2 = this.position2; - - if (position2 == null || posKind2 == null) { - return UnDefType.UNDEF; - } - - switch (posKindCoords) { - case PRIMARY_POSITION: - /* - * Primary rail of a bottom-up shade, or lower rail of a dual action shade: => INVERTED - */ - if (posKindCoords.equals(posKind2)) { - return new PercentType(100 - (int) Math.round(position2.doubleValue() / MAX_SHADE * 100)); - } - break; - - case SECONDARY_POSITION: - /* - * Secondary, upper rail of a dual action shade: => NOT INVERTED - */ - if (posKindCoords.equals(posKind2)) { - return new PercentType((int) Math.round(position2.doubleValue() / MAX_SHADE * 100)); - } - break; - - /* - * Vane angle of the primary rail of a bottom-up single action shade: => NOT INVERTED - */ - case VANE_TILT_POSITION: - if (posKindCoords.equals(posKind2)) { - int max = shadeCapabilities.supportsTilt180() ? MAX_SHADE : MAX_VANE; - return new PercentType((int) Math.round((double) Math.min(position2.intValue(), max) / max * 100)); - } - break; - - case ERROR_UNKNOWN: - case NONE: - // fall through, return UNDEF - } - return UnDefType.UNDEF; - } - - /** - * Detect if the ShadePosition has a posKindN value indicating potential support for a secondary rail. - * - * @return true if the ShadePosition supports a secondary rail. - */ - public boolean secondaryRailDetected() { - return SECONDARY_POSITION.equals(posKind1) || SECONDARY_POSITION.equals(posKind2); - } - - /** - * Detect if the ShadePosition has both a posKindN value indicating potential support for tilt, AND a posKindN - * indicating support for a primary rail. i.e. it potentially supports tilt anywhere functionality. - * - * @return true if potential support for tilt anywhere functionality was detected. - */ - public boolean tiltAnywhereDetected() { - return ((PRIMARY_POSITION.equals(posKind1)) && (VANE_TILT_POSITION.equals(posKind2)) - || ((PRIMARY_POSITION.equals(posKind2) && (VANE_TILT_POSITION.equals(posKind1))))); - } - - /** - * Set the shade's position for the given actuator class resp. coordinate system. - * - * @param shadeCapabilities the shade Thing capabilities. - * @param posKindCoords the actuator class (coordinate system) whose state is to be changed. - * @param percent the new position value. - * @return this object. - */ - public ShadePosition setPosition(Capabilities shadeCapabilities, CoordinateSystem posKindCoords, int percent) { - logger.trace("setPosition(): capabilities={}, coords={}, percent={}", shadeCapabilities, posKindCoords, - percent); - // if necessary swap the order of position1 and position2 - if (PRIMARY_POSITION.equals(posKind2) && !PRIMARY_POSITION.equals(posKind1)) { - final Integer posKind2Temp = posKind2; - final Integer position2Temp = position2; - posKind2 = Integer.valueOf(posKind1); - position2 = Integer.valueOf(position1); - posKind1 = posKind2Temp != null ? posKind2Temp.intValue() : NONE.ordinal(); - position1 = position2Temp != null ? position2Temp.intValue() : 0; - } - - // delete position2 if it has an invalid position kind - if (ERROR_UNKNOWN.equals(posKind2) || NONE.equals(posKind2)) { - posKind2 = null; - position2 = null; - } - - // logic to set either position1 or position2 - switch (posKindCoords) { - case PRIMARY_POSITION: - if (shadeCapabilities.supportsPrimary()) { - setPosition1(shadeCapabilities, posKindCoords, percent); - } - break; - - case SECONDARY_POSITION: - if (shadeCapabilities.supportsSecondary()) { - if (shadeCapabilities.supportsPrimary()) { - setPosition2(shadeCapabilities, posKindCoords, percent); - } else { - setPosition1(shadeCapabilities, posKindCoords, percent); - } - } else if (shadeCapabilities.supportsSecondaryOverlapped()) { - setPosition1(shadeCapabilities, posKindCoords, percent); - } - break; - - case VANE_TILT_POSITION: - if (shadeCapabilities.supportsPrimary()) { - if (shadeCapabilities.supportsTiltOnClosed()) { - setPosition1(shadeCapabilities, posKindCoords, percent); - } else if (shadeCapabilities.supportsTiltAnywhere()) { - setPosition2(shadeCapabilities, posKindCoords, percent); - } - } else if (shadeCapabilities.supportsTiltAnywhere()) { - setPosition1(shadeCapabilities, posKindCoords, percent); - } - break; - - case ERROR_UNKNOWN: - case NONE: - // fall through, do nothing - } - return this; - } -} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/SurveyData.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/SurveyData.java deleted file mode 100644 index bfb5301bac..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/SurveyData.java +++ /dev/null @@ -1,34 +0,0 @@ -/** - * 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 com.google.gson.annotations.SerializedName; - -/** - * Survey data of a single Shade, as returned by an HD PowerView hub - * - * @author Jacob Laursen - Initial contribution - */ -@NonNullByDefault -public class SurveyData { - @SerializedName("neighbor_id") - public int neighborId; - public int rssi; - - @Override - public String toString() { - return String.format("{neighbor id:%d, rssi:%d}", neighborId, rssi); - } -} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/Times.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/Times.java deleted file mode 100644 index 0dbc911bfd..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/Times.java +++ /dev/null @@ -1,31 +0,0 @@ -/** - * 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.eclipse.jdt.annotation.Nullable; - -/** - * Times as part of {@link UserData} for an HD PowerView hub - * - * @author Jacob Laursen - Initial contribution - */ -@NonNullByDefault -public class Times { - public @Nullable String timezone; - public int localSunriseTimeInMinutes; - public int localSunsetTimeInMinutes; - public int currentOffset; - public double longitude; - public double latitude; -} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/UserData.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/UserData.java deleted file mode 100644 index 70c33a9189..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/UserData.java +++ /dev/null @@ -1,58 +0,0 @@ -/** - * 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 java.util.Base64; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; - -import com.google.gson.annotations.SerializedName; - -/** - * User data for an HD PowerView hub - * - * @author Jacob Laursen - Initial contribution - */ -@NonNullByDefault -public class UserData { - public @Nullable String hubName; - public boolean localTimeDataSet; - public boolean enableScheduledEvents; - public boolean editingEnabled; - public boolean setupCompleted; - public @Nullable String gateway; - public @Nullable String dns; - public boolean staticIp; - @SerializedName("_id") - public @Nullable String id; - public @Nullable Color color; - public boolean autoBackup; - public @Nullable String ip; - public @Nullable String macAddress; - public @Nullable String mask; - public boolean wireless; - public @Nullable HubFirmware firmware; - public @Nullable String serialNumber; - public @Nullable String rfIDInt; - public @Nullable String rfID; - public int rfStatus; - public @Nullable Times times; - public @Nullable String brand; - public boolean rcUp; - public boolean remoteConnectEnabled; - - public String getHubName() { - return hubName != null ? new String(Base64.getDecoder().decode(hubName)) : ""; - } -} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/requests/RepeaterBlinking.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/requests/RepeaterBlinking.java deleted file mode 100644 index ea3886af1f..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/requests/RepeaterBlinking.java +++ /dev/null @@ -1,39 +0,0 @@ -/** - * 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; - -/** - * State of a single Repeater for being updated by an HD PowerView Hub - * - * @author Jacob Laursen - Initial contribution - */ -@NonNullByDefault -public class RepeaterBlinking { - public Repeater repeater; - - public class Repeater { - public int id; - public boolean blinkEnabled; - - public Repeater(int id, boolean enable) { - this.id = id; - this.blinkEnabled = enable; - } - } - - public RepeaterBlinking(int id, boolean enable) { - repeater = new Repeater(id, enable); - } -} 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 deleted file mode 100644 index 960e95f587..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/requests/RepeaterColor.java +++ /dev/null @@ -1,40 +0,0 @@ -/** - * 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/requests/ShadeCalibrate.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/requests/ShadeCalibrate.java deleted file mode 100644 index e1ec80e487..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/requests/ShadeCalibrate.java +++ /dev/null @@ -1,30 +0,0 @@ -/** - * 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; - -/** - * A request to calibrate a shade - * - * @author Jacob Laursen - Initial contribution - */ -@NonNullByDefault -public class ShadeCalibrate { - - public ShadeMotion shade; - - public ShadeCalibrate() { - this.shade = new ShadeMotion(ShadeMotion.Type.CALIBRATE); - } -} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/requests/ShadeJog.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/requests/ShadeJog.java deleted file mode 100644 index 71fb0477a0..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/requests/ShadeJog.java +++ /dev/null @@ -1,30 +0,0 @@ -/** - * 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; - -/** - * A request to jog a shade for identification - * - * @author Jacob Laursen - Initial contribution - */ -@NonNullByDefault -public class ShadeJog { - - public ShadeMotion shade; - - public ShadeJog() { - this.shade = new ShadeMotion(ShadeMotion.Type.JOG); - } -} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/requests/ShadeMotion.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/requests/ShadeMotion.java deleted file mode 100644 index c6b16a0000..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/requests/ShadeMotion.java +++ /dev/null @@ -1,46 +0,0 @@ -/** - * 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; - -/** - * A motion directive for a shade - * - * @author Jacob Laursen - Initial contribution - */ -@NonNullByDefault -class ShadeMotion { - - public enum Type { - STOP("stop"), - JOG("jog"), - CALIBRATE("calibrate"); - - private String motion; - - Type(String motion) { - this.motion = motion; - } - - public String getMotion() { - return this.motion; - } - } - - public String motion; - - public ShadeMotion(Type motionType) { - this.motion = motionType.getMotion(); - } -} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/requests/ShadeMove.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/requests/ShadeMove.java deleted file mode 100644 index fe688f4f75..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/requests/ShadeMove.java +++ /dev/null @@ -1,31 +0,0 @@ -/** - * 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.ShadePosition; - -/** - * A request to set the position of a shade - * - * @author Andy Lintner - Initial contribution - */ -@NonNullByDefault -public class ShadeMove { - - public ShadePositions shade; - - public ShadeMove(ShadePosition position) { - this.shade = new ShadePositions(position); - } -} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/requests/ShadePositions.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/requests/ShadePositions.java deleted file mode 100644 index 1c544c047e..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/requests/ShadePositions.java +++ /dev/null @@ -1,31 +0,0 @@ -/** - * 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.ShadePosition; - -/** - * The position of a shade to set - * - * @author Andy Lintner - Initial contribution - */ -@NonNullByDefault -class ShadePositions { - - public ShadePosition positions; - - public ShadePositions(ShadePosition position) { - this.positions = position; - } -} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/requests/ShadeStop.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/requests/ShadeStop.java deleted file mode 100644 index ed7ab4c4b0..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/requests/ShadeStop.java +++ /dev/null @@ -1,30 +0,0 @@ -/** - * 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; - -/** - * A request to stop the movement of a shade - * - * @author Andrew Fiddian-Green - Initial contribution - */ -@NonNullByDefault -public class ShadeStop { - - public ShadeMotion shade; - - public ShadeStop() { - this.shade = new ShadeMotion(ShadeMotion.Type.STOP); - } -} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/FirmwareVersion.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/FirmwareVersion.java deleted file mode 100644 index d046f06a8d..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/FirmwareVersion.java +++ /dev/null @@ -1,28 +0,0 @@ -/** - * 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.responses; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; -import org.openhab.binding.hdpowerview.internal.api.HubFirmware; - -/** - * Firmware information for an HD PowerView hub - * - * @author Jacob Laursen - Initial contribution - */ -@NonNullByDefault -public class FirmwareVersion { - @Nullable - public HubFirmware firmware; -} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/Repeater.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/Repeater.java deleted file mode 100644 index 55ba66665b..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/Repeater.java +++ /dev/null @@ -1,26 +0,0 @@ -/** - * 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.responses; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; - -/** - * State of a single Repeater, as returned by an HD PowerView Hub - * - * @author Jacob Laursen - Initial contribution - */ -@NonNullByDefault -public class Repeater { - public @Nullable RepeaterData repeater; -} 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 deleted file mode 100644 index a083f91a35..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/RepeaterData.java +++ /dev/null @@ -1,40 +0,0 @@ -/** - * 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.responses; - -import java.util.Base64; - -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; - -/** - * Repeater data for a single Repeater, as returned by an HD PowerView Hub - * - * @author Jacob Laursen - Initial contribution - */ -@NonNullByDefault -public class RepeaterData { - public int id; - public @Nullable String name; - public int roomId; - 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/api/responses/Repeaters.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/Repeaters.java deleted file mode 100644 index 8b5f15b12f..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/Repeaters.java +++ /dev/null @@ -1,29 +0,0 @@ -/** - * 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.responses; - -import java.util.List; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; - -/** - * Repeaters connected to an HD PowerView Hub - * - * @author Jacob Laursen - Initial contribution - */ -@NonNullByDefault -public class Repeaters { - public @Nullable List repeaterData; - public @Nullable List repeaterIds; -} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/SceneCollections.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/SceneCollections.java deleted file mode 100644 index bef9e94b93..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/SceneCollections.java +++ /dev/null @@ -1,84 +0,0 @@ -/** - * 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.responses; - -import java.nio.charset.StandardCharsets; -import java.util.Base64; -import java.util.List; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; - -/** - * State of all Scene Collections in an HD PowerView hub - * - * @author Jacob Laursen - Initial contribution - */ -@NonNullByDefault -public class SceneCollections { - - public @Nullable List sceneCollectionData; - public @Nullable List sceneCollectionIds; - - /* - * the following SuppressWarnings annotation is because the Eclipse compiler - * does NOT expect a NonNullByDefault annotation on the inner class, since it is - * implicitly inherited from the outer class, whereas the Maven compiler always - * requires an explicit NonNullByDefault annotation on all classes - */ - @SuppressWarnings("null") - @NonNullByDefault - public static class SceneCollection implements Comparable { - public int id; - public @Nullable String name; - public int order; - public int colorId; - public int iconId; - - @Override - public boolean equals(@Nullable Object o) { - if (o == this) { - return true; - } - if (!(o instanceof SceneCollection)) { - return false; - } - SceneCollection other = (SceneCollection) o; - - return this.id == other.id && this.name.equals(other.name) && this.order == other.order - && this.colorId == other.colorId && this.iconId == other.iconId; - } - - @Override - public final int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + id; - result = prime * result + (name == null ? 0 : name.hashCode()); - result = prime * result + order; - result = prime * result + colorId; - result = prime * result + iconId; - - return result; - } - - @Override - public int compareTo(SceneCollection other) { - return Integer.compare(order, other.order); - } - - public String getName() { - return new String(Base64.getDecoder().decode(name), StandardCharsets.UTF_8); - } - } -} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/Scenes.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/Scenes.java deleted file mode 100644 index 5cb25a8aab..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/Scenes.java +++ /dev/null @@ -1,86 +0,0 @@ -/** - * 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.responses; - -import java.nio.charset.StandardCharsets; -import java.util.Base64; -import java.util.List; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; - -/** - * State of all Scenes in an HD PowerView hub - * - * @author Andy Lintner - Initial contribution - */ -@NonNullByDefault -public class Scenes { - - public @Nullable List sceneData; - public @Nullable List sceneIds; - - /* - * the following SuppressWarnings annotation is because the Eclipse compiler - * does NOT expect a NonNullByDefault annotation on the inner class, since it is - * implicitly inherited from the outer class, whereas the Maven compiler always - * requires an explicit NonNullByDefault annotation on all classes - */ - @SuppressWarnings("null") - @NonNullByDefault - public static class Scene implements Comparable { - public int id; - public @Nullable String name; - public int roomId; - public int order; - public int colorId; - public int iconId; - - @Override - public boolean equals(@Nullable Object o) { - if (o == this) { - return true; - } - if (!(o instanceof Scene)) { - return false; - } - Scene other = (Scene) o; - - return this.id == other.id && this.name.equals(other.name) && this.roomId == other.roomId - && this.order == other.order && this.colorId == other.colorId && this.iconId == other.iconId; - } - - @Override - public final int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + id; - result = prime * result + (name == null ? 0 : name.hashCode()); - result = prime * result + roomId; - result = prime * result + order; - result = prime * result + colorId; - result = prime * result + iconId; - - return result; - } - - @Override - public int compareTo(Scene other) { - return Integer.compare(order, other.order); - } - - public String getName() { - return new String(Base64.getDecoder().decode(name), StandardCharsets.UTF_8); - } - } -} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/ScheduledEvents.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/ScheduledEvents.java deleted file mode 100644 index e7ae6ac1ae..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/ScheduledEvents.java +++ /dev/null @@ -1,132 +0,0 @@ -/** - * 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.responses; - -import java.time.DayOfWeek; -import java.util.EnumSet; -import java.util.List; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; - -/** - * State of all Scheduled Events in an HD PowerView hub - * - * @author Jacob Laursen - Initial contribution - */ -@NonNullByDefault -public class ScheduledEvents { - - public static final EnumSet WEEKDAYS = EnumSet.of(DayOfWeek.MONDAY, DayOfWeek.TUESDAY, - DayOfWeek.WEDNESDAY, DayOfWeek.THURSDAY, DayOfWeek.FRIDAY); - - public static final EnumSet WEEKENDS = EnumSet.of(DayOfWeek.SATURDAY, DayOfWeek.SUNDAY); - - public static final int SCHEDULED_EVENT_TYPE_TIME = 0; - public static final int SCHEDULED_EVENT_TYPE_SUNRISE = 1; - public static final int SCHEDULED_EVENT_TYPE_SUNSET = 2; - - public @Nullable List scheduledEventData; - public @Nullable List scheduledEventIds; - - /* - * the following SuppressWarnings annotation is because the Eclipse compiler - * does NOT expect a NonNullByDefault annotation on the inner class, since it is - * implicitly inherited from the outer class, whereas the Maven compiler always - * requires an explicit NonNullByDefault annotation on all classes - */ - @SuppressWarnings("null") - @NonNullByDefault - public static class ScheduledEvent { - public int id; - public boolean enabled; - public int sceneId; - public int sceneCollectionId; - public boolean daySunday; - public boolean dayMonday; - public boolean dayTuesday; - public boolean dayWednesday; - public boolean dayThursday; - public boolean dayFriday; - public boolean daySaturday; - public int eventType; - public int hour; - public int minute; - - @Override - public boolean equals(@Nullable Object o) { - if (o == this) { - return true; - } - if (!(o instanceof ScheduledEvent)) { - return false; - } - ScheduledEvent other = (ScheduledEvent) o; - - return this.id == other.id && this.enabled == other.enabled && this.sceneId == other.sceneId - && this.sceneCollectionId == other.sceneCollectionId && this.daySunday == other.daySunday - && this.dayMonday == other.dayMonday && this.dayTuesday == other.dayTuesday - && this.dayWednesday == other.dayWednesday && this.dayThursday == other.dayThursday - && this.dayFriday == other.dayFriday && this.daySaturday == other.daySaturday - && this.eventType == other.eventType && this.hour == other.hour && this.minute == other.minute; - } - - @Override - public final int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + id; - result = prime * result + (enabled ? 1 : 0); - result = prime * result + sceneId; - result = prime * result + sceneCollectionId; - result = prime * result + (daySunday ? 1 : 0); - result = prime * result + (dayMonday ? 1 : 0); - result = prime * result + (dayTuesday ? 1 : 0); - result = prime * result + (dayWednesday ? 1 : 0); - result = prime * result + (dayThursday ? 1 : 0); - result = prime * result + (dayFriday ? 1 : 0); - result = prime * result + (daySaturday ? 1 : 0); - result = prime * result + eventType; - result = prime * result + hour; - result = prime * result + minute; - - return result; - } - - public EnumSet getDays() { - EnumSet days = EnumSet.noneOf(DayOfWeek.class); - if (daySunday) { - days.add(DayOfWeek.SUNDAY); - } - if (dayMonday) { - days.add(DayOfWeek.MONDAY); - } - if (dayTuesday) { - days.add(DayOfWeek.TUESDAY); - } - if (dayWednesday) { - days.add(DayOfWeek.WEDNESDAY); - } - if (dayThursday) { - days.add(DayOfWeek.THURSDAY); - } - if (dayFriday) { - days.add(DayOfWeek.FRIDAY); - } - if (daySaturday) { - days.add(DayOfWeek.SATURDAY); - } - return days; - } - } -} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/Shade.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/Shade.java deleted file mode 100644 index 69da937839..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/Shade.java +++ /dev/null @@ -1,28 +0,0 @@ -/** - * 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.responses; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; -import org.openhab.binding.hdpowerview.internal.api.responses.Shades.ShadeData; - -/** - * State of a single Shade, as returned by an HD PowerView hub - * - * @author Andrew Fiddian-Green - Initial contribution - */ -@NonNullByDefault -public class Shade { - - public @Nullable ShadeData shade; -} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/Shades.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/Shades.java deleted file mode 100644 index 2746523b47..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/Shades.java +++ /dev/null @@ -1,70 +0,0 @@ -/** - * 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.responses; - -import java.util.Base64; -import java.util.List; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; -import org.openhab.binding.hdpowerview.internal.api.BatteryKind; -import org.openhab.binding.hdpowerview.internal.api.Firmware; -import org.openhab.binding.hdpowerview.internal.api.ShadePosition; - -/** - * State of all Shades, as returned by an HD PowerView hub - * - * @author Andy Lintner - Initial contribution - */ -@NonNullByDefault -public class Shades { - - public @Nullable List shadeData; - public @Nullable List shadeIds; - - /* - * the following SuppressWarnings annotation is because the Eclipse compiler - * does NOT expect a NonNullByDefault annotation on the inner class, since it is - * implicitly inherited from the outer class, whereas the Maven compiler always - * requires an explicit NonNullByDefault annotation on all classes - */ - @SuppressWarnings("null") - @NonNullByDefault - public static class ShadeData { - public int id; - public @Nullable String name; - public int roomId; - public int groupId; - public int order; - public int type; - public double batteryStrength; - public int batteryStatus; - public boolean batteryIsLow; - public @Nullable ShadePosition positions; - public @Nullable Boolean timedOut; - public int signalStrength; - public @Nullable Integer capabilities; - public @Nullable Firmware firmware; - public @Nullable Firmware motor; - // note: in old JSON batteryKind was a string but now it's a number; fortunately GSON string accepts either - public @Nullable String batteryKind; - - public String getName() { - return new String(Base64.getDecoder().decode(name)); - } - - public BatteryKind getBatteryKind() { - return BatteryKind.fromString(batteryKind); - } - } -} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/Survey.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/Survey.java deleted file mode 100644 index 21709fe1a0..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/Survey.java +++ /dev/null @@ -1,34 +0,0 @@ -/** - * 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.responses; - -import java.util.List; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; -import org.openhab.binding.hdpowerview.internal.api.SurveyData; - -import com.google.gson.annotations.SerializedName; - -/** - * Survey data of a single Shade, as returned by an HD PowerView hub - * - * @author Jacob Laursen - Initial contribution - */ -@NonNullByDefault -public class Survey { - @SerializedName("shade_id") - public int shadeId; - @SerializedName("survey") - public @Nullable List surveyData; -} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/UserDataResponse.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/UserDataResponse.java deleted file mode 100644 index 3509ffdb85..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/api/responses/UserDataResponse.java +++ /dev/null @@ -1,27 +0,0 @@ -/** - * 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.responses; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; -import org.openhab.binding.hdpowerview.internal.api.UserData; - -/** - * Response with {@link UserData} for an HD PowerView hub - * - * @author Jacob Laursen - Initial contribution - */ -@NonNullByDefault -public class UserDataResponse { - public @Nullable UserData userData; -} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/builders/AutomationChannelBuilder.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/builders/AutomationChannelBuilder.java index 10782b22b9..2147346946 100644 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/builders/AutomationChannelBuilder.java +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/builders/AutomationChannelBuilder.java @@ -25,10 +25,9 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.openhab.binding.hdpowerview.internal.HDPowerViewBindingConstants; import org.openhab.binding.hdpowerview.internal.HDPowerViewTranslationProvider; -import org.openhab.binding.hdpowerview.internal.api.responses.SceneCollections.SceneCollection; -import org.openhab.binding.hdpowerview.internal.api.responses.Scenes.Scene; -import org.openhab.binding.hdpowerview.internal.api.responses.ScheduledEvents; -import org.openhab.binding.hdpowerview.internal.api.responses.ScheduledEvents.ScheduledEvent; +import org.openhab.binding.hdpowerview.internal.dto.Scene; +import org.openhab.binding.hdpowerview.internal.dto.SceneCollection; +import org.openhab.binding.hdpowerview.internal.dto.ScheduledEvent; import org.openhab.core.library.CoreItemFactory; import org.openhab.core.thing.Channel; import org.openhab.core.thing.ChannelGroupUID; @@ -193,10 +192,10 @@ public class AutomationChannelBuilder extends BaseChannelBuilder { String timeString, daysString; switch (scheduledEvent.eventType) { - case ScheduledEvents.SCHEDULED_EVENT_TYPE_TIME: + case ScheduledEvent.SCHEDULED_EVENT_TYPE_TIME: timeString = LocalTime.of(scheduledEvent.hour, scheduledEvent.minute).toString(); break; - case ScheduledEvents.SCHEDULED_EVENT_TYPE_SUNRISE: + case ScheduledEvent.SCHEDULED_EVENT_TYPE_SUNRISE: if (scheduledEvent.minute == 0) { timeString = translationProvider.getText("dynamic-channel.automation.at-sunrise"); } else if (scheduledEvent.minute < 0) { @@ -207,7 +206,7 @@ public class AutomationChannelBuilder extends BaseChannelBuilder { getFormattedTimeOffset(scheduledEvent.minute)); } break; - case ScheduledEvents.SCHEDULED_EVENT_TYPE_SUNSET: + case ScheduledEvent.SCHEDULED_EVENT_TYPE_SUNSET: if (scheduledEvent.minute == 0) { timeString = translationProvider.getText("dynamic-channel.automation.at-sunset"); } else if (scheduledEvent.minute < 0) { @@ -225,9 +224,9 @@ public class AutomationChannelBuilder extends BaseChannelBuilder { EnumSet days = scheduledEvent.getDays(); if (EnumSet.allOf(DayOfWeek.class).equals(days)) { daysString = translationProvider.getText("dynamic-channel.automation.all-days"); - } else if (ScheduledEvents.WEEKDAYS.equals(days)) { + } else if (ScheduledEvent.WEEKDAYS.equals(days)) { daysString = translationProvider.getText("dynamic-channel.automation.weekdays"); - } else if (ScheduledEvents.WEEKENDS.equals(days)) { + } else if (ScheduledEvent.WEEKENDS.equals(days)) { daysString = translationProvider.getText("dynamic-channel.automation.weekends"); } else { StringJoiner joiner = new StringJoiner(", "); diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/builders/SceneChannelBuilder.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/builders/SceneChannelBuilder.java index 01c05137e9..213a60def0 100644 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/builders/SceneChannelBuilder.java +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/builders/SceneChannelBuilder.java @@ -18,7 +18,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.openhab.binding.hdpowerview.internal.HDPowerViewBindingConstants; import org.openhab.binding.hdpowerview.internal.HDPowerViewTranslationProvider; -import org.openhab.binding.hdpowerview.internal.api.responses.Scenes.Scene; +import org.openhab.binding.hdpowerview.internal.dto.Scene; import org.openhab.core.library.CoreItemFactory; import org.openhab.core.thing.Channel; import org.openhab.core.thing.ChannelGroupUID; diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/builders/SceneGroupChannelBuilder.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/builders/SceneGroupChannelBuilder.java index 4cc4436ea2..d4dbd2cde6 100644 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/builders/SceneGroupChannelBuilder.java +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/builders/SceneGroupChannelBuilder.java @@ -18,7 +18,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.openhab.binding.hdpowerview.internal.HDPowerViewBindingConstants; import org.openhab.binding.hdpowerview.internal.HDPowerViewTranslationProvider; -import org.openhab.binding.hdpowerview.internal.api.responses.SceneCollections.SceneCollection; +import org.openhab.binding.hdpowerview.internal.dto.SceneCollection; import org.openhab.core.library.CoreItemFactory; import org.openhab.core.thing.Channel; import org.openhab.core.thing.ChannelGroupUID; diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/console/HDPowerViewCommandExtension.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/console/HDPowerViewCommandExtension.java index 4252f8d57b..2e16968bab 100644 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/console/HDPowerViewCommandExtension.java +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/console/HDPowerViewCommandExtension.java @@ -19,8 +19,8 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.openhab.binding.hdpowerview.internal.HDPowerViewBindingConstants; import org.openhab.binding.hdpowerview.internal.HDPowerViewWebTargets; -import org.openhab.binding.hdpowerview.internal.api.responses.RepeaterData; -import org.openhab.binding.hdpowerview.internal.api.responses.Shades.ShadeData; +import org.openhab.binding.hdpowerview.internal.dto.ShadeData; +import org.openhab.binding.hdpowerview.internal.dto.responses.RepeaterData; import org.openhab.binding.hdpowerview.internal.exceptions.HubException; import org.openhab.binding.hdpowerview.internal.handler.HDPowerViewHubHandler; import org.openhab.core.io.console.Console; diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/discovery/HDPowerViewDeviceDiscoveryService.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/discovery/HDPowerViewDeviceDiscoveryService.java index 98d108befc..65bc262365 100644 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/discovery/HDPowerViewDeviceDiscoveryService.java +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/discovery/HDPowerViewDeviceDiscoveryService.java @@ -21,13 +21,13 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.openhab.binding.hdpowerview.internal.HDPowerViewBindingConstants; import org.openhab.binding.hdpowerview.internal.HDPowerViewWebTargets; -import org.openhab.binding.hdpowerview.internal.api.responses.RepeaterData; -import org.openhab.binding.hdpowerview.internal.api.responses.Shades; -import org.openhab.binding.hdpowerview.internal.api.responses.Shades.ShadeData; import org.openhab.binding.hdpowerview.internal.config.HDPowerViewRepeaterConfiguration; import org.openhab.binding.hdpowerview.internal.config.HDPowerViewShadeConfiguration; import org.openhab.binding.hdpowerview.internal.database.ShadeCapabilitiesDatabase; import org.openhab.binding.hdpowerview.internal.database.ShadeCapabilitiesDatabase.Capabilities; +import org.openhab.binding.hdpowerview.internal.dto.ShadeData; +import org.openhab.binding.hdpowerview.internal.dto.responses.RepeaterData; +import org.openhab.binding.hdpowerview.internal.dto.responses.Shades; import org.openhab.binding.hdpowerview.internal.exceptions.HubException; import org.openhab.binding.hdpowerview.internal.exceptions.HubInvalidResponseException; import org.openhab.binding.hdpowerview.internal.exceptions.HubMaintenanceException; diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/BatteryKind.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/BatteryKind.java new file mode 100644 index 0000000000..a3b79bf47f --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/BatteryKind.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.dto; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; + +/** + * An enum for the type of power supply in a shade. + * + * @author Andrew Fiddian-Green - Initial contribution + */ +@NonNullByDefault +public enum BatteryKind { + ERROR_UNKNOWN(-1), + HARDWIRED_POWER_SUPPLY(1), + BATTERY_WAND(2), + RECHARGEABLE_BATTERY_WAND(3); + + private int batteryKind; + + private BatteryKind(int i) { + this.batteryKind = i; + } + + /** + * Determine the BatteryKind by parsing the given string value. + * + * @param value the string to parse, or null. + * @return the BatteryKind or ERROR_UNKNOWN in case of error. + */ + public static BatteryKind fromString(@Nullable String value) { + if (value != null) { + try { + int intValue = Integer.parseInt(value); + for (BatteryKind e : values()) { + if (e.batteryKind == intValue) { + return e; + } + } + } catch (NumberFormatException e) { + // fall through + } + } + return ERROR_UNKNOWN; + } +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/Color.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/Color.java new file mode 100644 index 0000000000..7179690638 --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/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.dto; + +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/dto/CoordinateSystem.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/CoordinateSystem.java new file mode 100644 index 0000000000..47c4a1bb7d --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/CoordinateSystem.java @@ -0,0 +1,111 @@ +/** + * 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.dto; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; + +/** + * Shade coordinate system (a.k.a. position kind), as returned by the HD PowerView hub. + * + * @param NONE a coordinate system that does not refer to any type of physical rail. + * @param PRIMARY_POSITION primary rail, whose coordinate value 0 means shade is closed. + * @param SECONDARY_POSITION secondary rail, whose coordinate value 0 means shade is open. + * @param VANE_TILT_POSITION vane/tilt operator, whose coordinate system is for vanes. + * @param ERROR_UNKNOWN unsupported coordinate system. + * + * @author Andy Lintner - Initial contribution of the original enum called + * ShadePositionKind + * + * @author Andrew Fiddian-Green - Rewritten as a new enum called + * CoordinateSystem to support secondary rail positions and be more + * explicit on coordinate directions and ranges + */ +@NonNullByDefault +public enum CoordinateSystem { + /*- + * Specifies the coordinate system used for the position of the shade. Top-down + * shades are in the same coordinate space as bottom-up shades. Shade position + * values for top-down shades would be reversed for bottom-up shades. For + * example, since 65535 is the open value for a bottom-up shade, it is the + * closed value for a top-down shade. The top-down/bottom-up shade is different + * in that instead of the top and bottom rail operating in one coordinate space + * like the top-down and the bottom-up, it operates in two where the top + * (middle) rail closed value is 0 and the bottom (primary) rail closed position + * is also 0 and fully open for both is 65535 + * + * The position element can take on multiple states depending on the family of + * shade under control. + * + * The ranges of position integer values are + * shades: 0..65535 + * vanes: 0..32767 + * + * Shade fully up: (top-down: open, bottom-up: closed) + * posKind: 1 {ZERO_IS_CLOSED} + * position: 65535 + * + * Shade and vane fully down: (top-down: closed, bottom-up: open) + * posKind: 1 {ZERO_IS_CLOSED} + * position1: 0 + * + * ALTERNATE: Shade and vane fully down: (top-down: closed, bottom-up: open) + * posKind: 3 {VANE_COORDS} + * position: 0 + * + * Shade fully down (closed) and vane fully up (open): + * posKind: 3 {VANE_COORDS} + * position: 32767 + * + * Dual action, secondary top-down shade fully up (closed): + * posKind: 2 {ZERO_IS_OPEN} + * position: 0 + * + * Dual action, secondary top-down shade fully down (open): + * posKind: 2 {ZERO_IS_OPEN} + * position: 65535 + * + */ + NONE, + PRIMARY_POSITION, + SECONDARY_POSITION, + VANE_TILT_POSITION, + ERROR_UNKNOWN; + + public static final int MAX_SHADE = 65535; + public static final int MAX_VANE = 32767; + + /** + * Converts an HD PowerView posKind integer value to a CoordinateSystem enum value. + * + * @param posKind input integer value. + * @return corresponding CoordinateSystem enum. + */ + public static CoordinateSystem fromPosKind(int posKind) { + try { + return CoordinateSystem.values()[posKind]; + } catch (ArrayIndexOutOfBoundsException e) { + return ERROR_UNKNOWN; + } + } + + /** + * Check if the coordinate system matches the given posKind. + * + * @param posKind + * @return true if equal. + */ + public boolean equals(@Nullable Integer posKind) { + return (posKind != null) && (posKind.intValue() == ordinal()); + } +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/Firmware.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/Firmware.java new file mode 100644 index 0000000000..c17d76e99e --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/Firmware.java @@ -0,0 +1,35 @@ +/** + * 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.dto; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; + +/** + * Firmware version information for HD PowerView components + * + * @author Jacob Laursen - Initial contribution + */ +@NonNullByDefault +public class Firmware { + @Nullable + public String name; + public int revision; + public int subRevision; + public int build; + + @Override + public String toString() { + return String.format("%d.%d.%d", revision, subRevision, build); + } +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/HubFirmware.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/HubFirmware.java new file mode 100644 index 0000000000..5deb23bd56 --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/HubFirmware.java @@ -0,0 +1,29 @@ +/** + * 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.dto; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; + +/** + * Firmware information for an HD PowerView hub + * + * @author Jacob Laursen - Initial contribution + */ +@NonNullByDefault +public class HubFirmware { + @Nullable + public Firmware mainProcessor; + @Nullable + public Firmware radio; +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/Scene.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/Scene.java new file mode 100644 index 0000000000..daf5601d6e --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/Scene.java @@ -0,0 +1,73 @@ +/** + * 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.dto; + +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import java.util.Objects; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; + +/** + * State of a single Scene, as returned by an HD PowerView Hub + * + * @author Jacob Laursen - Initial contribution + */ +@NonNullByDefault +public class Scene implements Comparable { + public int id; + public @Nullable String name; + public int roomId; + public int order; + public int colorId; + public int iconId; + + @Override + public boolean equals(@Nullable Object o) { + if (o == this) { + return true; + } + if (!(o instanceof Scene)) { + return false; + } + Scene other = (Scene) o; + + return this.id == other.id && Objects.equals(name, other.name) && this.roomId == other.roomId + && this.order == other.order && this.colorId == other.colorId && this.iconId == other.iconId; + } + + @Override + public final int hashCode() { + final int prime = 31; + int result = 1; + String name = this.name; + result = prime * result + id; + result = prime * result + (name == null ? 0 : name.hashCode()); + result = prime * result + roomId; + result = prime * result + order; + result = prime * result + colorId; + result = prime * result + iconId; + + return result; + } + + @Override + public int compareTo(Scene other) { + return Integer.compare(order, other.order); + } + + public String getName() { + return new String(Base64.getDecoder().decode(name), StandardCharsets.UTF_8); + } +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/SceneCollection.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/SceneCollection.java new file mode 100644 index 0000000000..35e4f3ce07 --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/SceneCollection.java @@ -0,0 +1,71 @@ +/** + * 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.dto; + +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import java.util.Objects; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; + +/** + * State of a single Scene Collection, as returned by an HD PowerView Hub + * + * @author Jacob Laursen - Initial contribution + */ +@NonNullByDefault +public class SceneCollection implements Comparable { + public int id; + public @Nullable String name; + public int order; + public int colorId; + public int iconId; + + @Override + public boolean equals(@Nullable Object o) { + if (o == this) { + return true; + } + if (!(o instanceof SceneCollection)) { + return false; + } + SceneCollection other = (SceneCollection) o; + + return this.id == other.id && Objects.equals(name, other.name) && this.order == other.order + && this.colorId == other.colorId && this.iconId == other.iconId; + } + + @Override + public final int hashCode() { + final int prime = 31; + int result = 1; + String name = this.name; + result = prime * result + id; + result = prime * result + (name == null ? 0 : name.hashCode()); + result = prime * result + order; + result = prime * result + colorId; + result = prime * result + iconId; + + return result; + } + + @Override + public int compareTo(SceneCollection other) { + return Integer.compare(order, other.order); + } + + public String getName() { + return new String(Base64.getDecoder().decode(name), StandardCharsets.UTF_8); + } +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/ScheduledEvent.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/ScheduledEvent.java new file mode 100644 index 0000000000..16c9de0c91 --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/ScheduledEvent.java @@ -0,0 +1,117 @@ +/** + * 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.dto; + +import java.time.DayOfWeek; +import java.util.EnumSet; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; + +/** + * State of a single Scheduled Event, as returned by an HD PowerView Hub + * + * @author Jacob Laursen - Initial contribution + */ +@NonNullByDefault +public class ScheduledEvent { + public static final EnumSet WEEKDAYS = EnumSet.of(DayOfWeek.MONDAY, DayOfWeek.TUESDAY, + DayOfWeek.WEDNESDAY, DayOfWeek.THURSDAY, DayOfWeek.FRIDAY); + + public static final EnumSet WEEKENDS = EnumSet.of(DayOfWeek.SATURDAY, DayOfWeek.SUNDAY); + + public static final int SCHEDULED_EVENT_TYPE_TIME = 0; + public static final int SCHEDULED_EVENT_TYPE_SUNRISE = 1; + public static final int SCHEDULED_EVENT_TYPE_SUNSET = 2; + + public int id; + public boolean enabled; + public int sceneId; + public int sceneCollectionId; + public boolean daySunday; + public boolean dayMonday; + public boolean dayTuesday; + public boolean dayWednesday; + public boolean dayThursday; + public boolean dayFriday; + public boolean daySaturday; + public int eventType; + public int hour; + public int minute; + + @Override + public boolean equals(@Nullable Object o) { + if (o == this) { + return true; + } + if (!(o instanceof ScheduledEvent)) { + return false; + } + ScheduledEvent other = (ScheduledEvent) o; + + return this.id == other.id && this.enabled == other.enabled && this.sceneId == other.sceneId + && this.sceneCollectionId == other.sceneCollectionId && this.daySunday == other.daySunday + && this.dayMonday == other.dayMonday && this.dayTuesday == other.dayTuesday + && this.dayWednesday == other.dayWednesday && this.dayThursday == other.dayThursday + && this.dayFriday == other.dayFriday && this.daySaturday == other.daySaturday + && this.eventType == other.eventType && this.hour == other.hour && this.minute == other.minute; + } + + @Override + public final int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + id; + result = prime * result + (enabled ? 1 : 0); + result = prime * result + sceneId; + result = prime * result + sceneCollectionId; + result = prime * result + (daySunday ? 1 : 0); + result = prime * result + (dayMonday ? 1 : 0); + result = prime * result + (dayTuesday ? 1 : 0); + result = prime * result + (dayWednesday ? 1 : 0); + result = prime * result + (dayThursday ? 1 : 0); + result = prime * result + (dayFriday ? 1 : 0); + result = prime * result + (daySaturday ? 1 : 0); + result = prime * result + eventType; + result = prime * result + hour; + result = prime * result + minute; + + return result; + } + + public EnumSet getDays() { + EnumSet days = EnumSet.noneOf(DayOfWeek.class); + if (daySunday) { + days.add(DayOfWeek.SUNDAY); + } + if (dayMonday) { + days.add(DayOfWeek.MONDAY); + } + if (dayTuesday) { + days.add(DayOfWeek.TUESDAY); + } + if (dayWednesday) { + days.add(DayOfWeek.WEDNESDAY); + } + if (dayThursday) { + days.add(DayOfWeek.THURSDAY); + } + if (dayFriday) { + days.add(DayOfWeek.FRIDAY); + } + if (daySaturday) { + days.add(DayOfWeek.SATURDAY); + } + return days; + } +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/ShadeData.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/ShadeData.java new file mode 100644 index 0000000000..033426750b --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/ShadeData.java @@ -0,0 +1,52 @@ +/** + * 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.dto; + +import java.util.Base64; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; + +/** + * Shade data for a single Shade, as returned by an HD PowerView hub + * + * @author Jacob Laursen - Initial contribution + */ +@NonNullByDefault +public class ShadeData { + public int id; + public @Nullable String name; + public int roomId; + public int groupId; + public int order; + public int type; + public double batteryStrength; + public int batteryStatus; + public boolean batteryIsLow; + public @Nullable ShadePosition positions; + public @Nullable Boolean timedOut; + public int signalStrength; + public @Nullable Integer capabilities; + public @Nullable Firmware firmware; + public @Nullable Firmware motor; + // note: in old JSON batteryKind was a string but now it's a number; fortunately GSON string accepts either + public @Nullable String batteryKind; + + public String getName() { + return new String(Base64.getDecoder().decode(name)); + } + + public BatteryKind getBatteryKind() { + return BatteryKind.fromString(batteryKind); + } +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/ShadePosition.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/ShadePosition.java new file mode 100644 index 0000000000..d6bced8181 --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/ShadePosition.java @@ -0,0 +1,381 @@ +/** + * 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.dto; + +import static org.openhab.binding.hdpowerview.internal.dto.CoordinateSystem.*; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.openhab.binding.hdpowerview.internal.database.ShadeCapabilitiesDatabase.Capabilities; +import org.openhab.core.library.types.PercentType; +import org.openhab.core.types.State; +import org.openhab.core.types.UnDefType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The position of a single shade, as returned by the HD PowerView hub + * + * @author Andy Lintner - Initial contribution + * @author Andrew Fiddian-Green - Added support for secondary rail positions + */ +@NonNullByDefault +public class ShadePosition { + + private final transient Logger logger = LoggerFactory.getLogger(ShadePosition.class); + + /** + * Primary actuator position. + */ + private int posKind1; + private int position1; + + /** + * Secondary actuator position. + * + * Here we have to use Integer objects rather than just int primitives because these are secondary optional position + * elements in the JSON payload, so the GSON de-serializer might leave them as null. + */ + private @Nullable Integer posKind2 = null; + private @Nullable Integer position2 = null; + + public ShadePosition() { + } + + /** + * Get the shade's State for the given actuator class resp. coordinate system. + * + * @param shadeCapabilities the shade Thing capabilities. + * @param posKindCoords the actuator class (coordinate system) whose state is to be returned. + * @return the current state. + */ + public State getState(Capabilities shadeCapabilities, CoordinateSystem posKindCoords) { + State result = getPosition1(shadeCapabilities, posKindCoords); + if (result == UnDefType.UNDEF) { + result = getPosition2(shadeCapabilities, posKindCoords); + } + logger.trace("getState(): capabilities={}, coords={} => result={}", shadeCapabilities, posKindCoords, result); + return result; + } + + /** + * Set the shade's position1 value for the given actuator class resp. coordinate system. + * + * @param shadeCapabilities the shade Thing capabilities. + * @param posKindCoords the actuator class (coordinate system) whose state is to be changed. + * @param percent the new position value. + */ + private void setPosition1(Capabilities shadeCapabilities, CoordinateSystem posKindCoords, int percent) { + switch (posKindCoords) { + case PRIMARY_POSITION: + /* + * Primary rail of a bottom-up shade, or lower rail of a dual action shade: => INVERTED + */ + if (shadeCapabilities.supportsPrimary() && shadeCapabilities.supportsSecondary()) { + // on dual rail shades constrain percent to not move the lower rail above the upper + State secondary = getState(shadeCapabilities, SECONDARY_POSITION); + if (secondary instanceof PercentType) { + int secPercent = ((PercentType) secondary).intValue(); + if (percent < secPercent) { + percent = secPercent; + } + } + } + posKind1 = posKindCoords.ordinal(); + position1 = MAX_SHADE - (int) Math.round((double) percent / 100 * MAX_SHADE); + break; + + case SECONDARY_POSITION: + /* + * Secondary, blackout shade a 'Duolite' shade: => INVERTED + * Secondary, upper rail of a dual action shade: => NOT INVERTED + */ + posKind1 = posKindCoords.ordinal(); + if (shadeCapabilities.supportsSecondaryOverlapped()) { + position1 = MAX_SHADE - (int) Math.round((double) percent / 100 * MAX_SHADE); + } else { + position1 = (int) Math.round((double) percent / 100 * MAX_SHADE); + } + break; + + case VANE_TILT_POSITION: + /* + * Vane angle of the primary rail of a bottom-up single action shade: => NOT INVERTED + */ + posKind1 = posKindCoords.ordinal(); + int max = shadeCapabilities.supportsTilt180() ? MAX_SHADE : MAX_VANE; + position1 = (int) Math.round((double) percent / 100 * max); + break; + + default: + posKind1 = CoordinateSystem.NONE.ordinal(); + position1 = 0; + } + } + + /** + * Get the shade's position1 State for the given actuator class resp. coordinate system. + * + * @param shadeCapabilities the shade Thing capabilities. + * @param posKindCoords the actuator class (coordinate system) whose state is to be returned. + * @return the State (or UNDEF if not available). + */ + private State getPosition1(Capabilities shadeCapabilities, CoordinateSystem posKindCoords) { + switch (posKindCoords) { + case PRIMARY_POSITION: + /* + * Primary rail of a bottom-up shade, or lower rail of a dual action shade: => INVERTED + */ + if (posKindCoords.equals(posKind1)) { + return new PercentType(100 - (int) Math.round((double) position1 / MAX_SHADE * 100)); + } + if (VANE_TILT_POSITION.equals(posKind1) && shadeCapabilities.supportsTiltOnClosed()) { + return PercentType.HUNDRED; + } + if (SECONDARY_POSITION.equals(posKind1) && shadeCapabilities.supportsSecondaryOverlapped()) { + return PercentType.HUNDRED; + } + break; + + case SECONDARY_POSITION: + /* + * Secondary, blackout shade a 'Duolite' shade: => INVERTED + * Secondary, upper rail of a dual action shade: => NOT INVERTED + */ + if (posKindCoords.equals(posKind1)) { + if (shadeCapabilities.supportsSecondaryOverlapped()) { + return new PercentType(100 - (int) Math.round((double) position1 / MAX_SHADE * 100)); + } + return new PercentType((int) Math.round((double) position1 / MAX_SHADE * 100)); + } + if (!SECONDARY_POSITION.equals(posKind1) && shadeCapabilities.supportsSecondaryOverlapped()) { + return PercentType.ZERO; + } + break; + + case VANE_TILT_POSITION: + /* + * Vane angle of the primary rail of a bottom-up single action shade: => NOT INVERTED + * + * If the shades are not open, the vane position is undefined; if the the shades + * are exactly open then the vanes are at zero; otherwise return the actual vane + * position itself + * + * note: sometimes the hub may return a value of position1 > MAX_VANE (seems to + * be a bug in the hub) so we avoid an out of range exception via the Math.min() + * function below.. + */ + if (posKindCoords.equals(posKind1)) { + int max = shadeCapabilities.supportsTilt180() ? MAX_SHADE : MAX_VANE; + return new PercentType((int) Math.round((double) Math.min(position1, max) / max * 100)); + } + if (PRIMARY_POSITION.equals(posKind1) && shadeCapabilities.supportsTiltOnClosed()) { + return position1 != 0 ? UnDefType.UNDEF : PercentType.ZERO; + } + if (SECONDARY_POSITION.equals(posKind1) && shadeCapabilities.supportsSecondaryOverlapped() + && shadeCapabilities.supportsTiltOnClosed()) { + return PercentType.HUNDRED; + } + break; + + case ERROR_UNKNOWN: + case NONE: + // fall through, return UNDEF + } + return UnDefType.UNDEF; + } + + /** + * Set the shade's position2 value for the given actuator class resp. coordinate system. + * + * @param shadeCapabilities the shade Thing capabilities. + * @param posKindCoords the actuator class (coordinate system) whose state is to be changed. + * @param percent the new position value. + */ + private void setPosition2(Capabilities shadeCapabilities, CoordinateSystem posKindCoords, int percent) { + switch (posKindCoords) { + case PRIMARY_POSITION: + /* + * Primary rail of a bottom-up shade, or lower rail of a dual action shade: => INVERTED + */ + posKind2 = posKindCoords.ordinal(); + position2 = Integer.valueOf(MAX_SHADE - (int) Math.round((double) percent / 100 * MAX_SHADE)); + break; + + case SECONDARY_POSITION: + /* + * Secondary, upper rail of a dual action shade: => NOT INVERTED + */ + if (shadeCapabilities.supportsPrimary() && shadeCapabilities.supportsSecondary()) { + // on dual rail shades constrain percent to not move the upper rail below the lower + State primary = getState(shadeCapabilities, PRIMARY_POSITION); + if (primary instanceof PercentType) { + int primaryPercent = ((PercentType) primary).intValue(); + if (percent > primaryPercent) { + percent = primaryPercent; + } + } + } + posKind2 = posKindCoords.ordinal(); + position2 = Integer.valueOf((int) Math.round((double) percent / 100 * MAX_SHADE)); + break; + + case VANE_TILT_POSITION: + posKind2 = posKindCoords.ordinal(); + int max = shadeCapabilities.supportsTilt180() ? MAX_SHADE : MAX_VANE; + position2 = Integer.valueOf((int) Math.round((double) percent / 100 * max)); + break; + + default: + posKind2 = null; + position2 = null; + } + } + + /** + * Get the shade's position2 State for the given actuator class resp. coordinate system. + * + * @param shadeCapabilities the shade Thing capabilities. + * @param posKindCoords the actuator class (coordinate system) whose state is to be returned. + * @return the State (or UNDEF if not available). + */ + private State getPosition2(Capabilities shadeCapabilities, CoordinateSystem posKindCoords) { + Integer posKind2 = this.posKind2; + Integer position2 = this.position2; + + if (position2 == null || posKind2 == null) { + return UnDefType.UNDEF; + } + + switch (posKindCoords) { + case PRIMARY_POSITION: + /* + * Primary rail of a bottom-up shade, or lower rail of a dual action shade: => INVERTED + */ + if (posKindCoords.equals(posKind2)) { + return new PercentType(100 - (int) Math.round(position2.doubleValue() / MAX_SHADE * 100)); + } + break; + + case SECONDARY_POSITION: + /* + * Secondary, upper rail of a dual action shade: => NOT INVERTED + */ + if (posKindCoords.equals(posKind2)) { + return new PercentType((int) Math.round(position2.doubleValue() / MAX_SHADE * 100)); + } + break; + + /* + * Vane angle of the primary rail of a bottom-up single action shade: => NOT INVERTED + */ + case VANE_TILT_POSITION: + if (posKindCoords.equals(posKind2)) { + int max = shadeCapabilities.supportsTilt180() ? MAX_SHADE : MAX_VANE; + return new PercentType((int) Math.round((double) Math.min(position2.intValue(), max) / max * 100)); + } + break; + + case ERROR_UNKNOWN: + case NONE: + // fall through, return UNDEF + } + return UnDefType.UNDEF; + } + + /** + * Detect if the ShadePosition has a posKindN value indicating potential support for a secondary rail. + * + * @return true if the ShadePosition supports a secondary rail. + */ + public boolean secondaryRailDetected() { + return SECONDARY_POSITION.equals(posKind1) || SECONDARY_POSITION.equals(posKind2); + } + + /** + * Detect if the ShadePosition has both a posKindN value indicating potential support for tilt, AND a posKindN + * indicating support for a primary rail. i.e. it potentially supports tilt anywhere functionality. + * + * @return true if potential support for tilt anywhere functionality was detected. + */ + public boolean tiltAnywhereDetected() { + return ((PRIMARY_POSITION.equals(posKind1)) && (VANE_TILT_POSITION.equals(posKind2)) + || ((PRIMARY_POSITION.equals(posKind2) && (VANE_TILT_POSITION.equals(posKind1))))); + } + + /** + * Set the shade's position for the given actuator class resp. coordinate system. + * + * @param shadeCapabilities the shade Thing capabilities. + * @param posKindCoords the actuator class (coordinate system) whose state is to be changed. + * @param percent the new position value. + * @return this object. + */ + public ShadePosition setPosition(Capabilities shadeCapabilities, CoordinateSystem posKindCoords, int percent) { + logger.trace("setPosition(): capabilities={}, coords={}, percent={}", shadeCapabilities, posKindCoords, + percent); + // if necessary swap the order of position1 and position2 + if (PRIMARY_POSITION.equals(posKind2) && !PRIMARY_POSITION.equals(posKind1)) { + final Integer posKind2Temp = posKind2; + final Integer position2Temp = position2; + posKind2 = Integer.valueOf(posKind1); + position2 = Integer.valueOf(position1); + posKind1 = posKind2Temp != null ? posKind2Temp.intValue() : NONE.ordinal(); + position1 = position2Temp != null ? position2Temp.intValue() : 0; + } + + // delete position2 if it has an invalid position kind + if (ERROR_UNKNOWN.equals(posKind2) || NONE.equals(posKind2)) { + posKind2 = null; + position2 = null; + } + + // logic to set either position1 or position2 + switch (posKindCoords) { + case PRIMARY_POSITION: + if (shadeCapabilities.supportsPrimary()) { + setPosition1(shadeCapabilities, posKindCoords, percent); + } + break; + + case SECONDARY_POSITION: + if (shadeCapabilities.supportsSecondary()) { + if (shadeCapabilities.supportsPrimary()) { + setPosition2(shadeCapabilities, posKindCoords, percent); + } else { + setPosition1(shadeCapabilities, posKindCoords, percent); + } + } else if (shadeCapabilities.supportsSecondaryOverlapped()) { + setPosition1(shadeCapabilities, posKindCoords, percent); + } + break; + + case VANE_TILT_POSITION: + if (shadeCapabilities.supportsPrimary()) { + if (shadeCapabilities.supportsTiltOnClosed()) { + setPosition1(shadeCapabilities, posKindCoords, percent); + } else if (shadeCapabilities.supportsTiltAnywhere()) { + setPosition2(shadeCapabilities, posKindCoords, percent); + } + } else if (shadeCapabilities.supportsTiltAnywhere()) { + setPosition1(shadeCapabilities, posKindCoords, percent); + } + break; + + case ERROR_UNKNOWN: + case NONE: + // fall through, do nothing + } + return this; + } +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/SurveyData.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/SurveyData.java new file mode 100644 index 0000000000..7f3da5ff9c --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/SurveyData.java @@ -0,0 +1,34 @@ +/** + * 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.dto; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +import com.google.gson.annotations.SerializedName; + +/** + * Survey data of a single Shade, as returned by an HD PowerView hub + * + * @author Jacob Laursen - Initial contribution + */ +@NonNullByDefault +public class SurveyData { + @SerializedName("neighbor_id") + public int neighborId; + public int rssi; + + @Override + public String toString() { + return String.format("{neighbor id:%d, rssi:%d}", neighborId, rssi); + } +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/Times.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/Times.java new file mode 100644 index 0000000000..33a9bc99f3 --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/Times.java @@ -0,0 +1,31 @@ +/** + * 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.dto; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; + +/** + * Times as part of {@link UserData} for an HD PowerView hub + * + * @author Jacob Laursen - Initial contribution + */ +@NonNullByDefault +public class Times { + public @Nullable String timezone; + public int localSunriseTimeInMinutes; + public int localSunsetTimeInMinutes; + public int currentOffset; + public double longitude; + public double latitude; +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/UserData.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/UserData.java new file mode 100644 index 0000000000..fd36992246 --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/UserData.java @@ -0,0 +1,58 @@ +/** + * 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.dto; + +import java.util.Base64; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; + +import com.google.gson.annotations.SerializedName; + +/** + * User data for an HD PowerView hub + * + * @author Jacob Laursen - Initial contribution + */ +@NonNullByDefault +public class UserData { + public @Nullable String hubName; + public boolean localTimeDataSet; + public boolean enableScheduledEvents; + public boolean editingEnabled; + public boolean setupCompleted; + public @Nullable String gateway; + public @Nullable String dns; + public boolean staticIp; + @SerializedName("_id") + public @Nullable String id; + public @Nullable Color color; + public boolean autoBackup; + public @Nullable String ip; + public @Nullable String macAddress; + public @Nullable String mask; + public boolean wireless; + public @Nullable HubFirmware firmware; + public @Nullable String serialNumber; + public @Nullable String rfIDInt; + public @Nullable String rfID; + public int rfStatus; + public @Nullable Times times; + public @Nullable String brand; + public boolean rcUp; + public boolean remoteConnectEnabled; + + public String getHubName() { + return hubName != null ? new String(Base64.getDecoder().decode(hubName)) : ""; + } +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/requests/RepeaterBlinking.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/requests/RepeaterBlinking.java new file mode 100644 index 0000000000..e50a308448 --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/requests/RepeaterBlinking.java @@ -0,0 +1,39 @@ +/** + * 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.dto.requests; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * State of a single Repeater for being updated by an HD PowerView Hub + * + * @author Jacob Laursen - Initial contribution + */ +@NonNullByDefault +public class RepeaterBlinking { + public Repeater repeater; + + public class Repeater { + public int id; + public boolean blinkEnabled; + + public Repeater(int id, boolean enable) { + this.id = id; + this.blinkEnabled = enable; + } + } + + public RepeaterBlinking(int id, boolean enable) { + repeater = new Repeater(id, enable); + } +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/requests/RepeaterColor.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/requests/RepeaterColor.java new file mode 100644 index 0000000000..fc317e7aa1 --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/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.dto.requests; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.binding.hdpowerview.internal.dto.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/dto/requests/ShadeCalibrate.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/requests/ShadeCalibrate.java new file mode 100644 index 0000000000..0d1d50ec9d --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/requests/ShadeCalibrate.java @@ -0,0 +1,30 @@ +/** + * 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.dto.requests; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * A request to calibrate a shade + * + * @author Jacob Laursen - Initial contribution + */ +@NonNullByDefault +public class ShadeCalibrate { + + public ShadeMotion shade; + + public ShadeCalibrate() { + this.shade = new ShadeMotion(ShadeMotion.Type.CALIBRATE); + } +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/requests/ShadeJog.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/requests/ShadeJog.java new file mode 100644 index 0000000000..b1317a7eab --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/requests/ShadeJog.java @@ -0,0 +1,30 @@ +/** + * 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.dto.requests; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * A request to jog a shade for identification + * + * @author Jacob Laursen - Initial contribution + */ +@NonNullByDefault +public class ShadeJog { + + public ShadeMotion shade; + + public ShadeJog() { + this.shade = new ShadeMotion(ShadeMotion.Type.JOG); + } +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/requests/ShadeMotion.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/requests/ShadeMotion.java new file mode 100644 index 0000000000..f5aeb57a53 --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/requests/ShadeMotion.java @@ -0,0 +1,46 @@ +/** + * 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.dto.requests; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * A motion directive for a shade + * + * @author Jacob Laursen - Initial contribution + */ +@NonNullByDefault +class ShadeMotion { + + public enum Type { + STOP("stop"), + JOG("jog"), + CALIBRATE("calibrate"); + + private String motion; + + Type(String motion) { + this.motion = motion; + } + + public String getMotion() { + return this.motion; + } + } + + public String motion; + + public ShadeMotion(Type motionType) { + this.motion = motionType.getMotion(); + } +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/requests/ShadeMove.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/requests/ShadeMove.java new file mode 100644 index 0000000000..4f87fdf0c3 --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/requests/ShadeMove.java @@ -0,0 +1,31 @@ +/** + * 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.dto.requests; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.binding.hdpowerview.internal.dto.ShadePosition; + +/** + * A request to set the position of a shade + * + * @author Andy Lintner - Initial contribution + */ +@NonNullByDefault +public class ShadeMove { + + public ShadePositions shade; + + public ShadeMove(ShadePosition position) { + this.shade = new ShadePositions(position); + } +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/requests/ShadePositions.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/requests/ShadePositions.java new file mode 100644 index 0000000000..fd98950f5d --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/requests/ShadePositions.java @@ -0,0 +1,31 @@ +/** + * 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.dto.requests; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.binding.hdpowerview.internal.dto.ShadePosition; + +/** + * The position of a shade to set + * + * @author Andy Lintner - Initial contribution + */ +@NonNullByDefault +class ShadePositions { + + public ShadePosition positions; + + public ShadePositions(ShadePosition position) { + this.positions = position; + } +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/requests/ShadeStop.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/requests/ShadeStop.java new file mode 100644 index 0000000000..34f47f038c --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/requests/ShadeStop.java @@ -0,0 +1,30 @@ +/** + * 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.dto.requests; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * A request to stop the movement of a shade + * + * @author Andrew Fiddian-Green - Initial contribution + */ +@NonNullByDefault +public class ShadeStop { + + public ShadeMotion shade; + + public ShadeStop() { + this.shade = new ShadeMotion(ShadeMotion.Type.STOP); + } +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/responses/FirmwareVersion.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/responses/FirmwareVersion.java new file mode 100644 index 0000000000..34b9f202eb --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/responses/FirmwareVersion.java @@ -0,0 +1,28 @@ +/** + * 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.dto.responses; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.openhab.binding.hdpowerview.internal.dto.HubFirmware; + +/** + * Firmware information for an HD PowerView hub + * + * @author Jacob Laursen - Initial contribution + */ +@NonNullByDefault +public class FirmwareVersion { + @Nullable + public HubFirmware firmware; +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/responses/Repeater.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/responses/Repeater.java new file mode 100644 index 0000000000..d743626d96 --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/responses/Repeater.java @@ -0,0 +1,26 @@ +/** + * 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.dto.responses; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; + +/** + * State of a single Repeater, as returned by an HD PowerView Hub + * + * @author Jacob Laursen - Initial contribution + */ +@NonNullByDefault +public class Repeater { + public @Nullable RepeaterData repeater; +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/responses/RepeaterData.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/responses/RepeaterData.java new file mode 100644 index 0000000000..1b789637dd --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/responses/RepeaterData.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.dto.responses; + +import java.util.Base64; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.openhab.binding.hdpowerview.internal.dto.Color; +import org.openhab.binding.hdpowerview.internal.dto.Firmware; + +/** + * Repeater data for a single Repeater, as returned by an HD PowerView Hub + * + * @author Jacob Laursen - Initial contribution + */ +@NonNullByDefault +public class RepeaterData { + public int id; + public @Nullable String name; + public int roomId; + 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/dto/responses/Repeaters.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/responses/Repeaters.java new file mode 100644 index 0000000000..e1aa699b49 --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/responses/Repeaters.java @@ -0,0 +1,29 @@ +/** + * 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.dto.responses; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; + +/** + * Repeaters connected to an HD PowerView Hub + * + * @author Jacob Laursen - Initial contribution + */ +@NonNullByDefault +public class Repeaters { + public @Nullable List repeaterData; + public @Nullable List repeaterIds; +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/responses/SceneCollections.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/responses/SceneCollections.java new file mode 100644 index 0000000000..582178bc7b --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/responses/SceneCollections.java @@ -0,0 +1,30 @@ +/** + * 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.dto.responses; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.openhab.binding.hdpowerview.internal.dto.SceneCollection; + +/** + * State of all Scene Collections in an HD PowerView hub + * + * @author Jacob Laursen - Initial contribution + */ +@NonNullByDefault +public class SceneCollections { + public @Nullable List sceneCollectionData; + public @Nullable List sceneCollectionIds; +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/responses/Scenes.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/responses/Scenes.java new file mode 100644 index 0000000000..7458d6f90d --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/responses/Scenes.java @@ -0,0 +1,30 @@ +/** + * 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.dto.responses; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.openhab.binding.hdpowerview.internal.dto.Scene; + +/** + * State of all Scenes in an HD PowerView hub + * + * @author Andy Lintner - Initial contribution + */ +@NonNullByDefault +public class Scenes { + public @Nullable List sceneData; + public @Nullable List sceneIds; +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/responses/ScheduledEvents.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/responses/ScheduledEvents.java new file mode 100644 index 0000000000..4b4a8b416a --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/responses/ScheduledEvents.java @@ -0,0 +1,30 @@ +/** + * 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.dto.responses; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.openhab.binding.hdpowerview.internal.dto.ScheduledEvent; + +/** + * State of all Scheduled Events in an HD PowerView hub + * + * @author Jacob Laursen - Initial contribution + */ +@NonNullByDefault +public class ScheduledEvents { + public @Nullable List scheduledEventData; + public @Nullable List scheduledEventIds; +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/responses/Shade.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/responses/Shade.java new file mode 100644 index 0000000000..29b0794587 --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/responses/Shade.java @@ -0,0 +1,27 @@ +/** + * 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.dto.responses; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.openhab.binding.hdpowerview.internal.dto.ShadeData; + +/** + * State of a single Shade, as returned by an HD PowerView hub + * + * @author Andrew Fiddian-Green - Initial contribution + */ +@NonNullByDefault +public class Shade { + public @Nullable ShadeData shade; +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/responses/Shades.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/responses/Shades.java new file mode 100644 index 0000000000..ab177146eb --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/responses/Shades.java @@ -0,0 +1,30 @@ +/** + * 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.dto.responses; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.openhab.binding.hdpowerview.internal.dto.ShadeData; + +/** + * State of all Shades, as returned by an HD PowerView hub + * + * @author Andy Lintner - Initial contribution + */ +@NonNullByDefault +public class Shades { + public @Nullable List shadeData; + public @Nullable List shadeIds; +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/responses/Survey.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/responses/Survey.java new file mode 100644 index 0000000000..e55a1f99f8 --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/responses/Survey.java @@ -0,0 +1,34 @@ +/** + * 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.dto.responses; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.openhab.binding.hdpowerview.internal.dto.SurveyData; + +import com.google.gson.annotations.SerializedName; + +/** + * Survey data of a single Shade, as returned by an HD PowerView hub + * + * @author Jacob Laursen - Initial contribution + */ +@NonNullByDefault +public class Survey { + @SerializedName("shade_id") + public int shadeId; + @SerializedName("survey") + public @Nullable List surveyData; +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/responses/UserDataResponse.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/responses/UserDataResponse.java new file mode 100644 index 0000000000..15c4cbeae7 --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/dto/responses/UserDataResponse.java @@ -0,0 +1,27 @@ +/** + * 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.dto.responses; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.openhab.binding.hdpowerview.internal.dto.UserData; + +/** + * Response with {@link UserData} for an HD PowerView hub + * + * @author Jacob Laursen - Initial contribution + */ +@NonNullByDefault +public class UserDataResponse { + public @Nullable UserData userData; +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewHubHandler.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewHubHandler.java index b3991f3aad..7cfe8778f0 100644 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewHubHandler.java +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewHubHandler.java @@ -30,22 +30,22 @@ import org.eclipse.jetty.client.HttpClient; import org.openhab.binding.hdpowerview.internal.HDPowerViewBindingConstants; import org.openhab.binding.hdpowerview.internal.HDPowerViewTranslationProvider; import org.openhab.binding.hdpowerview.internal.HDPowerViewWebTargets; -import org.openhab.binding.hdpowerview.internal.api.Firmware; -import org.openhab.binding.hdpowerview.internal.api.HubFirmware; -import org.openhab.binding.hdpowerview.internal.api.UserData; -import org.openhab.binding.hdpowerview.internal.api.responses.SceneCollections; -import org.openhab.binding.hdpowerview.internal.api.responses.SceneCollections.SceneCollection; -import org.openhab.binding.hdpowerview.internal.api.responses.Scenes; -import org.openhab.binding.hdpowerview.internal.api.responses.Scenes.Scene; -import org.openhab.binding.hdpowerview.internal.api.responses.ScheduledEvents; -import org.openhab.binding.hdpowerview.internal.api.responses.ScheduledEvents.ScheduledEvent; -import org.openhab.binding.hdpowerview.internal.api.responses.Shades; -import org.openhab.binding.hdpowerview.internal.api.responses.Shades.ShadeData; import org.openhab.binding.hdpowerview.internal.builders.AutomationChannelBuilder; import org.openhab.binding.hdpowerview.internal.builders.SceneChannelBuilder; import org.openhab.binding.hdpowerview.internal.builders.SceneGroupChannelBuilder; import org.openhab.binding.hdpowerview.internal.config.HDPowerViewHubConfiguration; import org.openhab.binding.hdpowerview.internal.config.HDPowerViewShadeConfiguration; +import org.openhab.binding.hdpowerview.internal.dto.Firmware; +import org.openhab.binding.hdpowerview.internal.dto.HubFirmware; +import org.openhab.binding.hdpowerview.internal.dto.Scene; +import org.openhab.binding.hdpowerview.internal.dto.SceneCollection; +import org.openhab.binding.hdpowerview.internal.dto.ScheduledEvent; +import org.openhab.binding.hdpowerview.internal.dto.ShadeData; +import org.openhab.binding.hdpowerview.internal.dto.UserData; +import org.openhab.binding.hdpowerview.internal.dto.responses.SceneCollections; +import org.openhab.binding.hdpowerview.internal.dto.responses.Scenes; +import org.openhab.binding.hdpowerview.internal.dto.responses.ScheduledEvents; +import org.openhab.binding.hdpowerview.internal.dto.responses.Shades; import org.openhab.binding.hdpowerview.internal.exceptions.HubException; import org.openhab.binding.hdpowerview.internal.exceptions.HubInvalidResponseException; import org.openhab.binding.hdpowerview.internal.exceptions.HubMaintenanceException; 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 037c85184d..c8080fa2c3 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,10 +20,10 @@ import java.util.concurrent.TimeUnit; 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.dto.Color; +import org.openhab.binding.hdpowerview.internal.dto.Firmware; +import org.openhab.binding.hdpowerview.internal.dto.responses.RepeaterData; import org.openhab.binding.hdpowerview.internal.exceptions.HubException; import org.openhab.binding.hdpowerview.internal.exceptions.HubInvalidResponseException; import org.openhab.binding.hdpowerview.internal.exceptions.HubMaintenanceException; diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewShadeHandler.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewShadeHandler.java index 53e77e0425..f787ad0902 100644 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewShadeHandler.java +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewShadeHandler.java @@ -13,7 +13,7 @@ package org.openhab.binding.hdpowerview.internal.handler; import static org.openhab.binding.hdpowerview.internal.HDPowerViewBindingConstants.*; -import static org.openhab.binding.hdpowerview.internal.api.CoordinateSystem.*; +import static org.openhab.binding.hdpowerview.internal.dto.CoordinateSystem.*; import java.util.ArrayList; import java.util.HashMap; @@ -29,15 +29,15 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.openhab.binding.hdpowerview.internal.HDPowerViewBindingConstants; import org.openhab.binding.hdpowerview.internal.HDPowerViewWebTargets; -import org.openhab.binding.hdpowerview.internal.api.BatteryKind; -import org.openhab.binding.hdpowerview.internal.api.CoordinateSystem; -import org.openhab.binding.hdpowerview.internal.api.Firmware; -import org.openhab.binding.hdpowerview.internal.api.ShadePosition; -import org.openhab.binding.hdpowerview.internal.api.SurveyData; -import org.openhab.binding.hdpowerview.internal.api.responses.Shades.ShadeData; import org.openhab.binding.hdpowerview.internal.config.HDPowerViewShadeConfiguration; import org.openhab.binding.hdpowerview.internal.database.ShadeCapabilitiesDatabase; import org.openhab.binding.hdpowerview.internal.database.ShadeCapabilitiesDatabase.Capabilities; +import org.openhab.binding.hdpowerview.internal.dto.BatteryKind; +import org.openhab.binding.hdpowerview.internal.dto.CoordinateSystem; +import org.openhab.binding.hdpowerview.internal.dto.Firmware; +import org.openhab.binding.hdpowerview.internal.dto.ShadeData; +import org.openhab.binding.hdpowerview.internal.dto.ShadePosition; +import org.openhab.binding.hdpowerview.internal.dto.SurveyData; import org.openhab.binding.hdpowerview.internal.exceptions.HubException; import org.openhab.binding.hdpowerview.internal.exceptions.HubInvalidResponseException; import org.openhab.binding.hdpowerview.internal.exceptions.HubMaintenanceException; diff --git a/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/AutomationChannelBuilderTest.java b/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/AutomationChannelBuilderTest.java deleted file mode 100644 index ba6cb99574..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/AutomationChannelBuilderTest.java +++ /dev/null @@ -1,273 +0,0 @@ -/** - * 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; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.Mockito.mock; - -import java.util.ArrayList; -import java.util.Base64; -import java.util.List; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.openhab.binding.hdpowerview.internal.HDPowerViewBindingConstants; -import org.openhab.binding.hdpowerview.internal.HDPowerViewTranslationProvider; -import org.openhab.binding.hdpowerview.internal.api.responses.SceneCollections.SceneCollection; -import org.openhab.binding.hdpowerview.internal.api.responses.Scenes.Scene; -import org.openhab.binding.hdpowerview.internal.api.responses.ScheduledEvents; -import org.openhab.binding.hdpowerview.internal.api.responses.ScheduledEvents.ScheduledEvent; -import org.openhab.binding.hdpowerview.internal.builders.AutomationChannelBuilder; -import org.openhab.binding.hdpowerview.providers.MockedLocaleProvider; -import org.openhab.binding.hdpowerview.providers.MockedTranslationProvider; -import org.openhab.core.thing.Channel; -import org.openhab.core.thing.ChannelGroupUID; -import org.openhab.core.thing.ThingUID; -import org.osgi.framework.Bundle; -import org.slf4j.LoggerFactory; - -import ch.qos.logback.classic.Level; -import ch.qos.logback.classic.Logger; - -/** - * Unit tests for {@link AutomationChannelBuilder}. - * - * @author Jacob Laursen - Initial contribution - */ -@NonNullByDefault -public class AutomationChannelBuilderTest { - - private static final ChannelGroupUID CHANNEL_GROUP_UID = new ChannelGroupUID( - new ThingUID(HDPowerViewBindingConstants.BINDING_ID, AutomationChannelBuilderTest.class.getSimpleName()), - HDPowerViewBindingConstants.CHANNELTYPE_AUTOMATION_ENABLED); - - private static final HDPowerViewTranslationProvider TRANSLATION_PROVIDER = new HDPowerViewTranslationProvider( - mock(Bundle.class), new MockedTranslationProvider(), new MockedLocaleProvider()); - - private AutomationChannelBuilder builder = AutomationChannelBuilder.create(TRANSLATION_PROVIDER, CHANNEL_GROUP_UID); - private List scenes = new ArrayList<>(); - private List sceneCollections = new ArrayList<>(); - - @BeforeEach - private void setUp() { - final Logger logger = (Logger) LoggerFactory.getLogger(AutomationChannelBuilder.class); - logger.setLevel(Level.OFF); - builder = AutomationChannelBuilder.create(TRANSLATION_PROVIDER, CHANNEL_GROUP_UID); - - Scene scene = new Scene(); - scene.id = 1; - scene.name = Base64.getEncoder().encodeToString(("TestScene").getBytes()); - scenes = new ArrayList<>(List.of(scene)); - - SceneCollection sceneCollection = new SceneCollection(); - sceneCollection.id = 2; - sceneCollection.name = Base64.getEncoder().encodeToString(("TestSceneCollection").getBytes()); - sceneCollections = new ArrayList<>(List.of(sceneCollection)); - } - - @Test - public void sceneSunriseWeekends() { - ScheduledEvent scheduledEvent = createScheduledEventWithScene(ScheduledEvents.SCHEDULED_EVENT_TYPE_SUNRISE); - scheduledEvent.daySaturday = true; - scheduledEvent.daySunday = true; - - List scheduledEvents = new ArrayList<>(List.of(scheduledEvent)); - List channels = builder.withScenes(scenes).withScheduledEvents(scheduledEvents).build(); - - assertEquals(1, channels.size()); - assertEquals("TestScene, At sunrise, Weekends", channels.get(0).getLabel()); - } - - @Test - public void sceneSunsetWeekdays() { - ScheduledEvent scheduledEvent = createScheduledEventWithScene(ScheduledEvents.SCHEDULED_EVENT_TYPE_SUNSET); - scheduledEvent.dayMonday = true; - scheduledEvent.dayTuesday = true; - scheduledEvent.dayWednesday = true; - scheduledEvent.dayThursday = true; - scheduledEvent.dayFriday = true; - - List scheduledEvents = new ArrayList<>(List.of(scheduledEvent)); - List channels = builder.withScenes(scenes).withScheduledEvents(scheduledEvents).build(); - - assertEquals(1, channels.size()); - assertEquals("TestScene, At sunset, Weekdays", channels.get(0).getLabel()); - } - - @Test - public void sceneTimeAllDays() { - ScheduledEvent scheduledEvent = createScheduledEventWithScene(ScheduledEvents.SCHEDULED_EVENT_TYPE_TIME); - scheduledEvent.dayMonday = true; - scheduledEvent.dayTuesday = true; - scheduledEvent.dayWednesday = true; - scheduledEvent.dayThursday = true; - scheduledEvent.dayFriday = true; - scheduledEvent.daySaturday = true; - scheduledEvent.daySunday = true; - scheduledEvent.hour = 6; - scheduledEvent.minute = 30; - - List scheduledEvents = new ArrayList<>(List.of(scheduledEvent)); - List channels = builder.withScenes(scenes).withScheduledEvents(scheduledEvents).build(); - - assertEquals(1, channels.size()); - assertEquals("TestScene, 06:30, All days", channels.get(0).getLabel()); - } - - @Test - public void sceneMinutesBeforeSunriseMondayTuesday() { - ScheduledEvent scheduledEvent = createScheduledEventWithScene(ScheduledEvents.SCHEDULED_EVENT_TYPE_SUNRISE); - scheduledEvent.dayMonday = true; - scheduledEvent.dayTuesday = true; - scheduledEvent.minute = -15; - - List scheduledEvents = new ArrayList<>(List.of(scheduledEvent)); - List channels = builder.withScenes(scenes).withScheduledEvents(scheduledEvents).build(); - - assertEquals(1, channels.size()); - assertEquals("TestScene, 15m before sunrise, Mon, Tue", channels.get(0).getLabel()); - } - - @Test - public void sceneHoursMinutesAfterSunriseMonday() { - ScheduledEvent scheduledEvent = createScheduledEventWithScene(ScheduledEvents.SCHEDULED_EVENT_TYPE_SUNRISE); - scheduledEvent.dayMonday = true; - scheduledEvent.minute = 61; - - List scheduledEvents = new ArrayList<>(List.of(scheduledEvent)); - List channels = builder.withScenes(scenes).withScheduledEvents(scheduledEvents).build(); - - assertEquals(1, channels.size()); - assertEquals("TestScene, 1hr 1m after sunrise, Mon", channels.get(0).getLabel()); - } - - @Test - public void sceneMinutesBeforeSunsetWednesdayThursdayFriday() { - ScheduledEvent scheduledEvent = createScheduledEventWithScene(ScheduledEvents.SCHEDULED_EVENT_TYPE_SUNSET); - scheduledEvent.dayWednesday = true; - scheduledEvent.dayThursday = true; - scheduledEvent.dayFriday = true; - scheduledEvent.minute = -59; - - List scheduledEvents = new ArrayList<>(List.of(scheduledEvent)); - List channels = builder.withScenes(scenes).withScheduledEvents(scheduledEvents).build(); - - assertEquals(1, channels.size()); - assertEquals("TestScene, 59m before sunset, Wed, Thu, Fri", channels.get(0).getLabel()); - } - - @Test - public void sceneHourAfterSunsetFridaySaturdaySunday() { - ScheduledEvent scheduledEvent = createScheduledEventWithScene(ScheduledEvents.SCHEDULED_EVENT_TYPE_SUNSET); - scheduledEvent.dayFriday = true; - scheduledEvent.daySaturday = true; - scheduledEvent.daySunday = true; - scheduledEvent.minute = 60; - - List scheduledEvents = new ArrayList<>(List.of(scheduledEvent)); - List channels = builder.withScenes(scenes).withScheduledEvents(scheduledEvents).build(); - - assertEquals(1, channels.size()); - assertEquals("TestScene, 1hr after sunset, Fri, Sat, Sun", channels.get(0).getLabel()); - } - - @Test - public void sceneCollection() { - ScheduledEvent scheduledEvent = createScheduledEventWithSceneCollection( - ScheduledEvents.SCHEDULED_EVENT_TYPE_SUNRISE); - - List scheduledEvents = new ArrayList<>(List.of(scheduledEvent)); - List channels = builder.withSceneCollections(sceneCollections).withScheduledEvents(scheduledEvents) - .build(); - - assertEquals(1, channels.size()); - assertEquals("TestSceneCollection, At sunrise, ", channels.get(0).getLabel()); - } - - @Test - public void suppliedListIsUsed() { - ScheduledEvent scheduledEvent = createScheduledEventWithScene(ScheduledEvents.SCHEDULED_EVENT_TYPE_SUNRISE); - List scheduledEvents = new ArrayList<>(List.of(scheduledEvent)); - List existingChannels = new ArrayList<>(0); - List channels = builder.withScenes(scenes).withScheduledEvents(scheduledEvents) - .withChannels(existingChannels).build(); - - assertEquals(existingChannels, channels); - } - - @Test - public void emptyListWhenNoScheduledEvents() { - List channels = builder.build(); - - assertEquals(0, channels.size()); - } - - @Test - public void emptyListWhenNoScenesOrSceneCollections() { - ScheduledEvent scheduledEvent = createScheduledEventWithScene(ScheduledEvents.SCHEDULED_EVENT_TYPE_SUNRISE); - List scheduledEvents = new ArrayList<>(List.of(scheduledEvent)); - List channels = builder.withScheduledEvents(scheduledEvents).build(); - - assertEquals(0, channels.size()); - } - - @Test - public void emptyListWhenNoSceneForScheduledEvent() { - ScheduledEvent scheduledEvent = createScheduledEventWithSceneCollection( - ScheduledEvents.SCHEDULED_EVENT_TYPE_SUNRISE); - List scheduledEvents = new ArrayList<>(List.of(scheduledEvent)); - List channels = builder.withScenes(scenes).withScheduledEvents(scheduledEvents).build(); - - assertEquals(0, channels.size()); - } - - @Test - public void emptyListWhenNoSceneCollectionForScheduledEvent() { - ScheduledEvent scheduledEvent = createScheduledEventWithScene(ScheduledEvents.SCHEDULED_EVENT_TYPE_SUNRISE); - List scheduledEvents = new ArrayList<>(List.of(scheduledEvent)); - - List channels = builder.withSceneCollections(sceneCollections).withScheduledEvents(scheduledEvents) - .build(); - - assertEquals(0, channels.size()); - } - - @Test - public void groupAndIdAreCorrect() { - ScheduledEvent scheduledEvent = createScheduledEventWithScene(ScheduledEvents.SCHEDULED_EVENT_TYPE_SUNRISE); - scheduledEvent.id = 42; - List scheduledEvents = new ArrayList<>(List.of(scheduledEvent)); - List channels = builder.withScenes(scenes).withScheduledEvents(scheduledEvents).build(); - - assertEquals(1, channels.size()); - assertEquals(CHANNEL_GROUP_UID.getId(), channels.get(0).getUID().getGroupId()); - assertEquals(Integer.toString(scheduledEvent.id), channels.get(0).getUID().getIdWithoutGroup()); - } - - private ScheduledEvent createScheduledEventWithScene(int eventType) { - ScheduledEvent scheduledEvent = new ScheduledEvent(); - scheduledEvent.id = 1; - scheduledEvent.sceneId = scenes.get(0).id; - scheduledEvent.eventType = eventType; - return scheduledEvent; - } - - private ScheduledEvent createScheduledEventWithSceneCollection(int eventType) { - ScheduledEvent scheduledEvent = new ScheduledEvent(); - scheduledEvent.id = 1; - scheduledEvent.sceneCollectionId = sceneCollections.get(0).id; - scheduledEvent.eventType = eventType; - return scheduledEvent; - } -} diff --git a/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/HDPowerViewJUnitTests.java b/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/HDPowerViewJUnitTests.java deleted file mode 100644 index 19cd35c7c3..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/HDPowerViewJUnitTests.java +++ /dev/null @@ -1,191 +0,0 @@ -/** - * 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; - -import static org.junit.jupiter.api.Assertions.*; -import static org.openhab.binding.hdpowerview.internal.api.CoordinateSystem.*; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; -import java.util.List; -import java.util.Objects; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.junit.jupiter.api.Test; -import org.openhab.binding.hdpowerview.internal.api.BatteryKind; -import org.openhab.binding.hdpowerview.internal.api.ShadePosition; -import org.openhab.binding.hdpowerview.internal.api.responses.SceneCollections; -import org.openhab.binding.hdpowerview.internal.api.responses.SceneCollections.SceneCollection; -import org.openhab.binding.hdpowerview.internal.api.responses.Scenes; -import org.openhab.binding.hdpowerview.internal.api.responses.Scenes.Scene; -import org.openhab.binding.hdpowerview.internal.api.responses.Shades; -import org.openhab.binding.hdpowerview.internal.api.responses.Shades.ShadeData; -import org.openhab.binding.hdpowerview.internal.database.ShadeCapabilitiesDatabase; -import org.openhab.binding.hdpowerview.internal.database.ShadeCapabilitiesDatabase.Capabilities; -import org.openhab.core.library.types.PercentType; -import org.openhab.core.types.State; -import org.openhab.core.types.UnDefType; - -import com.google.gson.Gson; - -/** - * Unit tests for HD PowerView binding. - * - * @author Andrew Fiddian-Green - Initial contribution - * @author Jacob Laursen - Add support for scene groups - */ -@NonNullByDefault -public class HDPowerViewJUnitTests { - - private Gson gson = new Gson(); - - private T getObjectFromJson(String filename, Class clazz) throws IOException { - try (InputStream inputStream = HDPowerViewJUnitTests.class.getResourceAsStream(filename)) { - if (inputStream == null) { - throw new IOException("inputstream is null"); - } - byte[] bytes = inputStream.readAllBytes(); - if (bytes == null) { - throw new IOException("Resulting byte-array empty"); - } - String json = new String(bytes, StandardCharsets.UTF_8); - return Objects.requireNonNull(gson.fromJson(json, clazz)); - } - } - - /** - * Test generic JSON shades response. - */ - @Test - public void shadeNameIsDecoded() throws IOException { - Shades shades = getObjectFromJson("shades.json", Shades.class); - List shadeData = shades.shadeData; - assertNotNull(shadeData); - assertEquals(3, shadeData.size()); - ShadeData shade = shadeData.get(0); - assertEquals("Shade 2", shade.getName()); - } - - /** - * Test the BatteryKind decoding. - */ - @Test - public void testBatteryKind() throws IOException { - Shades shades = getObjectFromJson("shades.json", Shades.class); - List shadeData = shades.shadeData; - assertNotNull(shadeData); - ShadeData shade = shadeData.get(0); - assertEquals(BatteryKind.HARDWIRED_POWER_SUPPLY, shade.getBatteryKind()); - shade = shadeData.get(1); - assertEquals(BatteryKind.ERROR_UNKNOWN, shade.getBatteryKind()); - } - - /** - * Test generic JSON scene response. - */ - @Test - public void sceneNameIsDecoded() throws IOException { - Scenes scenes = getObjectFromJson("scenes.json", Scenes.class); - List sceneData = scenes.sceneData; - assertNotNull(sceneData); - assertEquals(4, sceneData.size()); - Scene scene = sceneData.get(0); - assertEquals("Door Open", scene.getName()); - } - - /** - * Test generic JSON scene collection response. - */ - @Test - public void sceneCollectionNameIsDecoded() throws IOException { - SceneCollections sceneCollections = getObjectFromJson("sceneCollections.json", SceneCollections.class); - - List sceneCollectionData = sceneCollections.sceneCollectionData; - assertNotNull(sceneCollectionData); - assertEquals(1, sceneCollectionData.size()); - - SceneCollection sceneCollection = sceneCollectionData.get(0); - assertEquals("Børn op", sceneCollection.getName()); - } - - /** - * Test the JSON parsing for a duette top down bottom up shade. - */ - @Test - public void duetteTopDownBottomUpShadeIsParsedCorrectly() throws IOException { - Shades shades = getObjectFromJson("duette.json", Shades.class); - List shadesData = shades.shadeData; - assertNotNull(shadesData); - - assertEquals(1, shadesData.size()); - ShadeData shadeData = shadesData.get(0); - assertNotNull(shadeData); - - assertEquals("Gardin 1", shadeData.getName()); - assertEquals(63778, shadeData.id); - - ShadePosition shadePos = shadeData.positions; - assertNotNull(shadePos); - - Integer capabilitiesValue = shadeData.capabilities; - assertNotNull(capabilitiesValue); - assertEquals(7, capabilitiesValue.intValue()); - ShadeCapabilitiesDatabase db = new ShadeCapabilitiesDatabase(); - Capabilities capabilities = db.getCapabilities(capabilitiesValue); - - State pos = shadePos.getState(capabilities, PRIMARY_POSITION); - assertEquals(PercentType.class, pos.getClass()); - assertEquals(59, ((PercentType) pos).intValue()); - - pos = shadePos.getState(capabilities, SECONDARY_POSITION); - assertEquals(PercentType.class, pos.getClass()); - assertEquals(35, ((PercentType) pos).intValue()); - - pos = shadePos.getState(capabilities, VANE_TILT_POSITION); - assertEquals(UnDefType.class, pos.getClass()); - - assertEquals(3, shadeData.batteryStatus); - - assertEquals(4, shadeData.signalStrength); - - assertEquals(8, shadeData.type); - - assertTrue(db.isTypeInDatabase(shadeData.type)); - assertTrue(db.isCapabilitiesInDatabase(capabilitiesValue.intValue())); - - assertEquals(db.getType(shadeData.type).getCapabilities(), capabilitiesValue.intValue()); - - assertTrue(db.getCapabilities(capabilitiesValue.intValue()).supportsSecondary()); - assertNotEquals(db.getType(shadeData.type).getCapabilities(), capabilitiesValue.intValue() + 1); - - // ==== when changing position1, position2 value is not changed (vice-versa) ==== - ShadePosition shadePosition = shadeData.positions; - assertNotNull(shadePosition); - // ==== position2 ==== - State position2Old = shadePosition.getState(capabilities, SECONDARY_POSITION); - shadePosition.setPosition(capabilities, PRIMARY_POSITION, 99); - State position2New = shadePosition.getState(capabilities, SECONDARY_POSITION); - assertEquals(PercentType.class, position2Old.getClass()); - assertEquals(PercentType.class, position2New.getClass()); - assertEquals(((PercentType) position2Old).intValue(), ((PercentType) position2New).intValue()); - - // ==== position2 ==== - State position1Old = shadePosition.getState(capabilities, PRIMARY_POSITION); - shadePosition.setPosition(capabilities, SECONDARY_POSITION, 99); - State position1New = shadePosition.getState(capabilities, PRIMARY_POSITION); - assertEquals(PercentType.class, position1Old.getClass()); - assertEquals(PercentType.class, position1New.getClass()); - assertEquals(((PercentType) position1Old).intValue(), ((PercentType) position1New).intValue()); - } -} diff --git a/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/OnlineCommunicationTest.java b/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/OnlineCommunicationTest.java deleted file mode 100644 index b8670bb91e..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/OnlineCommunicationTest.java +++ /dev/null @@ -1,219 +0,0 @@ -/** - * 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; - -import static org.junit.jupiter.api.Assertions.*; -import static org.openhab.binding.hdpowerview.internal.api.CoordinateSystem.*; - -import java.util.List; -import java.util.regex.Pattern; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jetty.client.HttpClient; -import org.junit.jupiter.api.Test; -import org.openhab.binding.hdpowerview.internal.HDPowerViewWebTargets; -import org.openhab.binding.hdpowerview.internal.api.ShadePosition; -import org.openhab.binding.hdpowerview.internal.api.responses.Scenes; -import org.openhab.binding.hdpowerview.internal.api.responses.Scenes.Scene; -import org.openhab.binding.hdpowerview.internal.api.responses.Shades; -import org.openhab.binding.hdpowerview.internal.api.responses.Shades.ShadeData; -import org.openhab.binding.hdpowerview.internal.database.ShadeCapabilitiesDatabase; -import org.openhab.binding.hdpowerview.internal.database.ShadeCapabilitiesDatabase.Capabilities; -import org.openhab.binding.hdpowerview.internal.exceptions.HubException; -import org.openhab.binding.hdpowerview.internal.exceptions.HubMaintenanceException; -import org.openhab.binding.hdpowerview.internal.exceptions.HubProcessingException; -import org.openhab.core.library.types.PercentType; -import org.openhab.core.types.State; - -/** - * Unit tests for HD PowerView binding. - * - * @author Andrew Fiddian-Green - Initial contribution - */ -@NonNullByDefault -public class OnlineCommunicationTest { - - private static final Pattern VALID_IP_V4_ADDRESS = Pattern - .compile("\\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\\.|$)){4}\\b"); - - /** - * Run a series of ONLINE tests on the communication with a hub. - * - * @param hubIPAddress must be a valid hub IP address to run the - * tests on; or an INVALID IP address to - * suppress the tests - * @param allowShadeMovementCommands set to true if you accept that the tests - * shall physically move the shades - */ - @Test - public void testOnlineCommunication() { - /* - * NOTE: in order to actually run these tests you must have a hub physically - * available, and its IP address must be correctly configured in the - * "hubIPAddress" string constant e.g. "192.168.1.123" - */ - String hubIPAddress = "192.168.1.xxx"; - - /* - * NOTE: set allowShadeMovementCommands = true if you accept physically moving - * the shades during these tests - */ - boolean allowShadeMovementCommands = false; - - if (VALID_IP_V4_ADDRESS.matcher(hubIPAddress).matches()) { - // ==== initialize stuff ==== - HttpClient client = new HttpClient(); - assertNotNull(client); - - // ==== start the client ==== - try { - client.start(); - assertTrue(client.isStarted()); - } catch (Exception e) { - fail(e.getMessage()); - } - - HDPowerViewWebTargets webTargets = new HDPowerViewWebTargets(client, hubIPAddress); - assertNotNull(webTargets); - - int shadeId = 0; - ShadePosition shadePos = null; - Shades shadesX = null; - - // ==== get all shades ==== - try { - shadesX = webTargets.getShades(); - assertNotNull(shadesX); - List shadesData = shadesX.shadeData; - assertNotNull(shadesData); - - assertTrue(!shadesData.isEmpty()); - ShadeData shadeData; - shadeData = shadesData.get(0); - assertNotNull(shadeData); - assertTrue(shadeData.getName().length() > 0); - shadePos = shadeData.positions; - assertNotNull(shadePos); - ShadeData shadeZero = shadesData.get(0); - assertNotNull(shadeZero); - shadeId = shadeZero.id; - assertNotEquals(0, shadeId); - - for (ShadeData shadexData : shadesData) { - String shadeName = shadexData.getName(); - assertNotNull(shadeName); - } - } catch (HubException e) { - fail(e.getMessage()); - } - - // ==== get all scenes ==== - int sceneId = 0; - try { - Scenes scenes = webTargets.getScenes(); - assertNotNull(scenes); - - List scenesData = scenes.sceneData; - assertNotNull(scenesData); - - assertTrue(!scenesData.isEmpty()); - Scene sceneZero = scenesData.get(0); - assertNotNull(sceneZero); - sceneId = sceneZero.id; - assertTrue(sceneId > 0); - - for (Scene scene : scenesData) { - String sceneName = scene.getName(); - assertNotNull(sceneName); - } - } catch (HubException e) { - fail(e.getMessage()); - } - - // ==== refresh a specific shade ==== - ShadeData shadeData = null; - try { - assertNotEquals(0, shadeId); - shadeData = webTargets.refreshShadePosition(shadeId); - } catch (HubException e) { - fail(e.getMessage()); - } - - // ==== move a specific shade ==== - try { - assertNotEquals(0, shadeId); - - if (shadeData != null) { - ShadePosition positions = shadeData.positions; - assertNotNull(positions); - Integer capabilitiesValue = shadeData.capabilities; - assertNotNull(capabilitiesValue); - - Capabilities capabilities = new ShadeCapabilitiesDatabase() - .getCapabilities(capabilitiesValue.intValue()); - - State pos = positions.getState(capabilities, PRIMARY_POSITION); - assertEquals(PercentType.class, pos.getClass()); - - int position = ((PercentType) pos).intValue(); - position = position + ((position <= 10) ? 5 : -5); - - ShadePosition targetPosition = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, - position); - assertNotNull(targetPosition); - - if (allowShadeMovementCommands) { - webTargets.moveShade(shadeId, targetPosition); - - ShadeData newData = webTargets.getShade(shadeId); - ShadePosition actualPosition = newData.positions; - assertNotNull(actualPosition); - assertEquals(targetPosition.getState(capabilities, PRIMARY_POSITION), - actualPosition.getState(capabilities, PRIMARY_POSITION)); - } - } - } catch (HubException e) { - fail(e.getMessage()); - } - - // ==== activate a specific scene ==== - if (allowShadeMovementCommands) { - try { - assertNotNull(sceneId); - webTargets.activateScene(sceneId); - } catch (HubProcessingException | HubMaintenanceException e) { - fail(e.getMessage()); - } - } - - // ==== test stop command ==== - if (allowShadeMovementCommands) { - try { - assertNotNull(sceneId); - webTargets.stopShade(shadeId); - } catch (HubException e) { - fail(e.getMessage()); - } - } - - // ==== stop the client ==== - if (client.isRunning()) { - try { - client.stop(); - } catch (Exception e) { - fail(e.getMessage()); - } - } - } - } -} diff --git a/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/SceneChannelBuilderTest.java b/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/SceneChannelBuilderTest.java deleted file mode 100644 index eca2a1f2e9..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/SceneChannelBuilderTest.java +++ /dev/null @@ -1,118 +0,0 @@ -/** - * 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; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.Mockito.mock; - -import java.util.ArrayList; -import java.util.Base64; -import java.util.List; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.openhab.binding.hdpowerview.internal.HDPowerViewBindingConstants; -import org.openhab.binding.hdpowerview.internal.HDPowerViewTranslationProvider; -import org.openhab.binding.hdpowerview.internal.api.responses.Scenes.Scene; -import org.openhab.binding.hdpowerview.internal.builders.SceneChannelBuilder; -import org.openhab.binding.hdpowerview.providers.MockedLocaleProvider; -import org.openhab.binding.hdpowerview.providers.MockedTranslationProvider; -import org.openhab.core.thing.Channel; -import org.openhab.core.thing.ChannelGroupUID; -import org.openhab.core.thing.ThingUID; -import org.openhab.core.thing.type.AutoUpdatePolicy; -import org.osgi.framework.Bundle; - -/** - * Unit tests for {@link SceneChannelBuilder}. - * - * @author Jacob Laursen - Initial contribution - */ -@NonNullByDefault -public class SceneChannelBuilderTest { - - private static final ChannelGroupUID CHANNEL_GROUP_UID = new ChannelGroupUID( - new ThingUID(HDPowerViewBindingConstants.BINDING_ID, SceneChannelBuilderTest.class.getSimpleName()), - HDPowerViewBindingConstants.CHANNELTYPE_SCENE_ACTIVATE); - - private static final HDPowerViewTranslationProvider TRANSLATION_PROVIDER = new HDPowerViewTranslationProvider( - mock(Bundle.class), new MockedTranslationProvider(), new MockedLocaleProvider()); - - private SceneChannelBuilder builder = SceneChannelBuilder.create(TRANSLATION_PROVIDER, CHANNEL_GROUP_UID); - - @BeforeEach - private void setUp() { - builder = SceneChannelBuilder.create(TRANSLATION_PROVIDER, CHANNEL_GROUP_UID); - } - - @Test - public void labelIsCorrect() { - List scenes = createScenes(); - List channels = builder.withScenes(scenes).build(); - - assertEquals(1, channels.size()); - assertEquals("TestScene", channels.get(0).getLabel()); - } - - @Test - public void descriptionIsCorrect() { - List scenes = createScenes(); - List channels = builder.withScenes(scenes).build(); - - assertEquals(1, channels.size()); - assertEquals("Activates the scene 'TestScene'", channels.get(0).getDescription()); - } - - @Test - public void groupAndIdAreCorrect() { - List scenes = createScenes(); - List channels = builder.withScenes(scenes).build(); - - assertEquals(1, channels.size()); - assertEquals(CHANNEL_GROUP_UID.getId(), channels.get(0).getUID().getGroupId()); - assertEquals(Integer.toString(scenes.get(0).id), channels.get(0).getUID().getIdWithoutGroup()); - } - - @Test - public void autoUpdatePolicyIsCorrect() { - List scenes = createScenes(); - List channels = builder.withScenes(scenes).build(); - - assertEquals(1, channels.size()); - assertEquals(AutoUpdatePolicy.VETO, channels.get(0).getAutoUpdatePolicy()); - } - - @Test - public void suppliedListIsUsed() { - List scenes = createScenes(); - List existingChannels = new ArrayList<>(0); - List channels = builder.withScenes(scenes).withChannels(existingChannels).build(); - - assertEquals(existingChannels, channels); - } - - @Test - public void emptyListWhenNoScenes() { - List channels = builder.build(); - - assertEquals(0, channels.size()); - } - - private List createScenes() { - Scene scene = new Scene(); - scene.id = 1; - scene.name = Base64.getEncoder().encodeToString(("TestScene").getBytes()); - return new ArrayList<>(List.of(scene)); - } -} diff --git a/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/SceneGroupChannelBuilderTest.java b/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/SceneGroupChannelBuilderTest.java deleted file mode 100644 index e2dc8b1b7a..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/SceneGroupChannelBuilderTest.java +++ /dev/null @@ -1,118 +0,0 @@ -/** - * 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; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.Mockito.mock; - -import java.util.ArrayList; -import java.util.Base64; -import java.util.List; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.openhab.binding.hdpowerview.internal.HDPowerViewBindingConstants; -import org.openhab.binding.hdpowerview.internal.HDPowerViewTranslationProvider; -import org.openhab.binding.hdpowerview.internal.api.responses.SceneCollections.SceneCollection; -import org.openhab.binding.hdpowerview.internal.builders.SceneGroupChannelBuilder; -import org.openhab.binding.hdpowerview.providers.MockedLocaleProvider; -import org.openhab.binding.hdpowerview.providers.MockedTranslationProvider; -import org.openhab.core.thing.Channel; -import org.openhab.core.thing.ChannelGroupUID; -import org.openhab.core.thing.ThingUID; -import org.openhab.core.thing.type.AutoUpdatePolicy; -import org.osgi.framework.Bundle; - -/** - * Unit tests for {@link SceneGroupChannelBuilder}. - * - * @author Jacob Laursen - Initial contribution - */ -@NonNullByDefault -public class SceneGroupChannelBuilderTest { - - private static final ChannelGroupUID CHANNEL_GROUP_UID = new ChannelGroupUID( - new ThingUID(HDPowerViewBindingConstants.BINDING_ID, SceneGroupChannelBuilderTest.class.getSimpleName()), - HDPowerViewBindingConstants.CHANNELTYPE_SCENE_GROUP_ACTIVATE); - - private static final HDPowerViewTranslationProvider TRANSLATION_PROVIDER = new HDPowerViewTranslationProvider( - mock(Bundle.class), new MockedTranslationProvider(), new MockedLocaleProvider()); - - private SceneGroupChannelBuilder builder = SceneGroupChannelBuilder.create(TRANSLATION_PROVIDER, CHANNEL_GROUP_UID); - - @BeforeEach - private void setUp() { - builder = SceneGroupChannelBuilder.create(TRANSLATION_PROVIDER, CHANNEL_GROUP_UID); - } - - @Test - public void labelIsCorrect() { - List sceneCollections = createSceneCollections(); - List channels = builder.withSceneCollections(sceneCollections).build(); - - assertEquals(1, channels.size()); - assertEquals("TestSceneCollection", channels.get(0).getLabel()); - } - - @Test - public void descriptionIsCorrect() { - List sceneCollections = createSceneCollections(); - List channels = builder.withSceneCollections(sceneCollections).build(); - - assertEquals(1, channels.size()); - assertEquals("Activates the scene group 'TestSceneCollection'", channels.get(0).getDescription()); - } - - @Test - public void groupAndIdAreCorrect() { - List sceneCollections = createSceneCollections(); - List channels = builder.withSceneCollections(sceneCollections).build(); - - assertEquals(1, channels.size()); - assertEquals(CHANNEL_GROUP_UID.getId(), channels.get(0).getUID().getGroupId()); - assertEquals(Integer.toString(sceneCollections.get(0).id), channels.get(0).getUID().getIdWithoutGroup()); - } - - @Test - public void autoUpdatePolicyIsCorrect() { - List sceneCollections = createSceneCollections(); - List channels = builder.withSceneCollections(sceneCollections).build(); - - assertEquals(1, channels.size()); - assertEquals(AutoUpdatePolicy.VETO, channels.get(0).getAutoUpdatePolicy()); - } - - @Test - public void suppliedListIsUsed() { - List sceneCollections = createSceneCollections(); - List existingChannels = new ArrayList<>(0); - List channels = builder.withSceneCollections(sceneCollections).withChannels(existingChannels).build(); - - assertEquals(existingChannels, channels); - } - - @Test - public void emptyListWhenNoSceneCollections() { - List channels = builder.build(); - - assertEquals(0, channels.size()); - } - - private List createSceneCollections() { - SceneCollection sceneCollection = new SceneCollection(); - sceneCollection.id = 1; - sceneCollection.name = Base64.getEncoder().encodeToString(("TestSceneCollection").getBytes()); - return new ArrayList<>(List.of(sceneCollection)); - } -} diff --git a/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/ShadePositionTest.java b/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/ShadePositionTest.java deleted file mode 100644 index 50dcd0e7ff..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/ShadePositionTest.java +++ /dev/null @@ -1,461 +0,0 @@ -/** - * 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; - -import static org.junit.jupiter.api.Assertions.*; -import static org.openhab.binding.hdpowerview.internal.api.CoordinateSystem.*; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.junit.jupiter.api.Test; -import org.openhab.binding.hdpowerview.internal.api.ShadePosition; -import org.openhab.binding.hdpowerview.internal.database.ShadeCapabilitiesDatabase; -import org.openhab.binding.hdpowerview.internal.database.ShadeCapabilitiesDatabase.Capabilities; -import org.openhab.core.library.types.PercentType; -import org.openhab.core.types.State; -import org.openhab.core.types.UnDefType; - -/** - * Unit tests for Shade Position setting and getting. - * - * @author Andrew Fiddian-Green - Initial contribution - */ -@NonNullByDefault -public class ShadePositionTest { - - private final ShadeCapabilitiesDatabase db = new ShadeCapabilitiesDatabase(); - - /** - * General tests of the database of known types. - */ - @Test - public void testKnownTypesDatabase() { - assertTrue(db.isTypeInDatabase(4)); - assertTrue(db.isCapabilitiesInDatabase(0)); - assertTrue(db.isCapabilitiesInDatabase(10)); - - assertTrue(db.getCapabilities(0).supportsPrimary()); - assertTrue(db.getCapabilities(1).supportsTiltOnClosed()); - assertTrue(db.getCapabilities(2).supportsTilt180()); - assertTrue(db.getCapabilities(2).supportsTiltAnywhere()); - assertTrue(db.getCapabilities(4).supportsTilt180()); - assertTrue(db.getCapabilities(4).supportsTiltAnywhere()); - assertTrue(db.getCapabilities(5).supportsTilt180()); - assertFalse(db.getCapabilities(5).supportsPrimary()); - assertTrue(db.getCapabilities(6).isPrimaryInverted()); - assertTrue(db.getCapabilities(7).supportsSecondary()); - assertTrue(db.getCapabilities(8).supportsSecondaryOverlapped()); - assertTrue(db.getCapabilities(9).supportsSecondaryOverlapped()); - assertTrue(db.getCapabilities(9).supportsTiltOnClosed()); - - assertEquals(db.getType(4).getCapabilities(), 0); - assertEquals(db.getType(-1).getCapabilities(), -1); - - assertFalse(db.isTypeInDatabase(99)); - assertFalse(db.isCapabilitiesInDatabase(99)); - - assertFalse(db.getCapabilities(0).isPrimaryInverted()); - assertFalse(db.getCapabilities(-1).isPrimaryInverted()); - assertFalse(db.getCapabilities(99).isPrimaryInverted()); - - assertFalse(db.getCapabilities(0).supportsSecondary()); - assertFalse(db.getCapabilities(-1).supportsSecondary()); - assertFalse(db.getCapabilities(99).supportsSecondary()); - } - - /** - * Helper method; test if shade position is a PercentType and that its value is correct. - * - * @param position the shade position - * @param value the test value to compare with - */ - private void assertShadePosition(State position, int value) { - assertEquals(PercentType.class, position.getClass()); - assertEquals(value, ((PercentType) position).intValue()); - } - - /** - * Test parsing of Capabilities 1 ShadePosition (shade fully up). - * - */ - @Test - public void testCaps1ShadePositionParsingFullyUp() { - Capabilities capabilities = db.getCapabilities(1); - ShadePosition test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 0); - assertNotNull(test); - assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 0); - assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), UnDefType.UNDEF); - assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF); - } - - /** - * Test parsing of Capabilities 1 ShadePosition (shade fully down (method 1)). - * - */ - @Test - public void testCaps1ShadePositionParsingShadeFullyDown1() { - Capabilities capabilities = db.getCapabilities(1); - ShadePosition test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 100); - assertNotNull(test); - assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100); - assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), UnDefType.UNDEF); - assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 0); - } - - /** - * Test parsing of Capabilities 1 ShadePosition (shade fully down (method 2)). - * - */ - @Test - public void testCaps1ShadePositionParsingShadeFullyDown2() { - Capabilities capabilities = db.getCapabilities(1); - ShadePosition test = new ShadePosition().setPosition(capabilities, VANE_TILT_POSITION, 0); - assertNotNull(test); - assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100); - assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), UnDefType.UNDEF); - assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 0); - } - - /** - * Test parsing of Capabilities 1 ShadePosition (shade fully down (method 2) and vane fully open). - * - */ - @Test - public void testCaps1ShadePositionParsingShadeFullyDownVaneOpen() { - Capabilities capabilities = db.getCapabilities(1); - ShadePosition test = new ShadePosition().setPosition(capabilities, VANE_TILT_POSITION, 88); - assertNotNull(test); - assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100); - assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), UnDefType.UNDEF); - assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 88); - } - - /** - * On dual rail shades, it should not be possible to drive the upper rail below the lower rail, or vice-versa. So - * the binding code applies constraints on setting such positions. This test checks that the constraint code is - * working. - */ - @Test - public void testDualRailConstraints() { - Capabilities capabilities = db.getCapabilities(7); - ShadePosition test = new ShadePosition(); - - // ==== OK !! primary at bottom, secondary at top ==== - test.setPosition(capabilities, PRIMARY_POSITION, 100).setPosition(capabilities, SECONDARY_POSITION, 0); - assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100); - assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0); - assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF); - - // ==== OK !! primary at middle, secondary at top ==== - test.setPosition(capabilities, PRIMARY_POSITION, 50).setPosition(capabilities, SECONDARY_POSITION, 0); - assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 50); - assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0); - assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF); - - // ==== OK !! primary at middle, secondary at middle ==== - test.setPosition(capabilities, PRIMARY_POSITION, 50).setPosition(capabilities, SECONDARY_POSITION, 50); - assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 50); - assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 50); - assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF); - - // ==== IMPOSSIBLE !! secondary at middle, primary above => test the constraining code ==== - test.setPosition(capabilities, SECONDARY_POSITION, 0).setPosition(capabilities, PRIMARY_POSITION, 100); - test.setPosition(capabilities, SECONDARY_POSITION, 40).setPosition(capabilities, PRIMARY_POSITION, 25); - assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 40); - assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 40); - assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF); - - // ==== OK !! secondary at middle, primary below ==== - test.setPosition(capabilities, SECONDARY_POSITION, 0).setPosition(capabilities, PRIMARY_POSITION, 100); - test.setPosition(capabilities, SECONDARY_POSITION, 50).setPosition(capabilities, PRIMARY_POSITION, 75); - assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 75); - assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 50); - assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF); - - // ==== IMPOSSIBLE !! primary at middle, secondary below => test the constraining code ==== - test.setPosition(capabilities, SECONDARY_POSITION, 0).setPosition(capabilities, PRIMARY_POSITION, 100); - test.setPosition(capabilities, PRIMARY_POSITION, 60).setPosition(capabilities, SECONDARY_POSITION, 75); - assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 60); - assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 60); - assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF); - - // ==== OK !! primary at middle, secondary above ==== - test.setPosition(capabilities, SECONDARY_POSITION, 0).setPosition(capabilities, PRIMARY_POSITION, 100); - test.setPosition(capabilities, PRIMARY_POSITION, 60).setPosition(capabilities, SECONDARY_POSITION, 25); - assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 60); - assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 25); - assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF); - } - - /** - * Test parsing of DuoLite shades having a secondary blackout shade. - * - */ - @Test - public void testDuoliteShadePositionParsing() { - // blackout shades have capabilities 8 - Capabilities capabilities = db.getCapabilities(8); - ShadePosition test; - - // both shades up - test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 0); - assertNotNull(test); - assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 0); - assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0); - assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF); - - // front shade 50% down - test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 50); - assertNotNull(test); - assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 50); - assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0); - assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF); - - // front shade 100% down, back shade 0% down - test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 100); - assertNotNull(test); - assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100); - assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0); - assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF); - - // front shade 100% down, back shade 0% down (ALTERNATE) - test = new ShadePosition().setPosition(capabilities, SECONDARY_POSITION, 0); - assertNotNull(test); - assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100); - assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0); - assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF); - - // front shade 100% down, back shade 50% down - test = new ShadePosition().setPosition(capabilities, SECONDARY_POSITION, 50); - assertNotNull(test); - assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100); - assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 50); - assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF); - - // front shade 100% down, back shade 100% down - test = new ShadePosition().setPosition(capabilities, SECONDARY_POSITION, 100); - assertNotNull(test); - assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100); - assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 100); - assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF); - } - - /** - * Test parsing of DuoLite shades having both a secondary blackout shade, and tilt functionality. - * - */ - @Test - public void testDuoliteTiltShadePositionParsing() { - // blackout shades with tilt have capabilities 9 - Capabilities capabilities = db.getCapabilities(9); - ShadePosition test; - - // front shade up - test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 0); - assertNotNull(test); - assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 0); - assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0); - assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF); - - // front shade 30% down - test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 30); - assertNotNull(test); - assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 30); - assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0); - assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF); - - // front shade 100% down - test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 100); - assertNotNull(test); - assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100); - assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0); - assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 0); - - // tilt 0% - test = new ShadePosition().setPosition(capabilities, VANE_TILT_POSITION, 0); - assertNotNull(test); - assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100); - assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0); - assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 0); - - // tilt 30% - test = new ShadePosition().setPosition(capabilities, VANE_TILT_POSITION, 30); - assertNotNull(test); - assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100); - assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0); - assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 30); - - // tilt 100% - test = new ShadePosition().setPosition(capabilities, VANE_TILT_POSITION, 100); - assertNotNull(test); - assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100); - assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0); - assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 100); - - // back shade 0% down - test = new ShadePosition().setPosition(capabilities, SECONDARY_POSITION, 0); - assertNotNull(test); - assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100); - assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0); - assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 100); - - // back shade 30% down - test = new ShadePosition().setPosition(capabilities, SECONDARY_POSITION, 30); - assertNotNull(test); - assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100); - assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 30); - assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 100); - - // back shade 100% down - test = new ShadePosition().setPosition(capabilities, SECONDARY_POSITION, 100); - assertNotNull(test); - assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100); - assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 100); - assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 100); - - // test constraints on impossible values: primary 30% => tilt 30% - test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 30).setPosition(capabilities, - VANE_TILT_POSITION, 30); - assertNotNull(test); - assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100); - assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0); - assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 30); - - // test constraints on impossible values: primary 30% => tilt 30% => back shade 30% down - test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 30) - .setPosition(capabilities, VANE_TILT_POSITION, 30).setPosition(capabilities, SECONDARY_POSITION, 30); - assertNotNull(test); - assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100); - assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 30); - assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 100); - } - - /** - * Test parsing of Capabilities 0 ShadePosition (shade fully up). - * - */ - @Test - public void testCaps0ShadePositionParsingFullyUp() { - Capabilities capabilities = db.getCapabilities(0); - ShadePosition test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 0); - assertNotNull(test); - assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 0); - assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), UnDefType.UNDEF); - assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF); - } - - /** - * Test parsing of Capabilities 0 ShadePosition (shade fully down). - * - */ - @Test - public void testCap0ShadePositionParsingShadeFullyDown() { - Capabilities capabilities = db.getCapabilities(0); - ShadePosition test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 100); - assertNotNull(test); - assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100); - assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), UnDefType.UNDEF); - assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF); - } - - /** - * Helper method; test if shade State is correct. - * - * @param actual the shade State - * @param target the test value to compare with - */ - private void assertShadePosition(State actual, State target) { - assertTrue(target.equals(actual)); - } - - /** - * Test parsing of Type 44 ShadePosition (shade fully up). - * - */ - @Test - public void testType44ShadePositionParsingFullyUp() { - Capabilities capabilities = db.getCapabilities(44, null); - ShadePosition test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 0); - assertNotNull(test); - assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 0); - assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), UnDefType.UNDEF); - assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF); - } - - /** - * Test parsing of Type 44 ShadePosition (shade fully down (method 2) and vane fully open). - * - */ - @Test - public void testType44ShadePositionParsingShadeFullyDownVaneOpen() { - Capabilities capabilities = db.getCapabilities(44, null); - ShadePosition test = new ShadePosition().setPosition(capabilities, VANE_TILT_POSITION, 88); - assertNotNull(test); - assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100); - assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), UnDefType.UNDEF); - assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 88); - } - - /** - * Test the getCapabilities functionality. - */ - @Test - public void testGetCapabilities() { - Capabilities caps; - /* - * - type not in database - * - null external capabilities - * => return default (0) - */ - caps = db.getCapabilities(0, null); - assertEquals(0, caps.getValue()); - /* - * - type not in database - * - valid external capabilities (1) - * => return external capabilities (1) - */ - caps = db.getCapabilities(0, 1); - assertEquals(1, caps.getValue()); - /* - * - type not in database - * - external capabilities not in database (99) - * => return default (0) - */ - caps = db.getCapabilities(0, 99); - assertEquals(0, caps.getValue()); - /* - * - type 62 in database - * - inherent capabilities (2) - * - null external capabilities - * => return inherent capabilities (2) - */ - caps = db.getCapabilities(62, null); - assertEquals(2, caps.getValue()); - /* - * - type 62 in database - * - inherent capabilities (2) - * - non matching external capabilities (1) - * => return external capabilities (1) - */ - caps = db.getCapabilities(62, 1); - assertEquals(1, caps.getValue()); - /* - * - type 44 in database - * - inherent capabilities (0) - * - with capabilitiesOverride (1) - * - non matching external capabilities (2) - * => return capabilitiesOverride (1) - */ - caps = db.getCapabilities(44, 2); - assertEquals(1, caps.getValue()); - } -} diff --git a/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/internal/AutomationChannelBuilderTest.java b/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/internal/AutomationChannelBuilderTest.java new file mode 100644 index 0000000000..6326ea587e --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/internal/AutomationChannelBuilderTest.java @@ -0,0 +1,270 @@ +/** + * 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; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.mock; + +import java.util.ArrayList; +import java.util.Base64; +import java.util.List; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.openhab.binding.hdpowerview.internal.builders.AutomationChannelBuilder; +import org.openhab.binding.hdpowerview.internal.dto.Scene; +import org.openhab.binding.hdpowerview.internal.dto.SceneCollection; +import org.openhab.binding.hdpowerview.internal.dto.ScheduledEvent; +import org.openhab.binding.hdpowerview.internal.providers.MockedLocaleProvider; +import org.openhab.binding.hdpowerview.internal.providers.MockedTranslationProvider; +import org.openhab.core.thing.Channel; +import org.openhab.core.thing.ChannelGroupUID; +import org.openhab.core.thing.ThingUID; +import org.osgi.framework.Bundle; +import org.slf4j.LoggerFactory; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; + +/** + * Unit tests for {@link AutomationChannelBuilder}. + * + * @author Jacob Laursen - Initial contribution + */ +@NonNullByDefault +public class AutomationChannelBuilderTest { + + private static final ChannelGroupUID CHANNEL_GROUP_UID = new ChannelGroupUID( + new ThingUID(HDPowerViewBindingConstants.BINDING_ID, AutomationChannelBuilderTest.class.getSimpleName()), + HDPowerViewBindingConstants.CHANNELTYPE_AUTOMATION_ENABLED); + + private static final HDPowerViewTranslationProvider TRANSLATION_PROVIDER = new HDPowerViewTranslationProvider( + mock(Bundle.class), new MockedTranslationProvider(), new MockedLocaleProvider()); + + private AutomationChannelBuilder builder = AutomationChannelBuilder.create(TRANSLATION_PROVIDER, CHANNEL_GROUP_UID); + private List scenes = new ArrayList<>(); + private List sceneCollections = new ArrayList<>(); + + @BeforeEach + private void setUp() { + final Logger logger = (Logger) LoggerFactory.getLogger(AutomationChannelBuilder.class); + logger.setLevel(Level.OFF); + builder = AutomationChannelBuilder.create(TRANSLATION_PROVIDER, CHANNEL_GROUP_UID); + + Scene scene = new Scene(); + scene.id = 1; + scene.name = Base64.getEncoder().encodeToString(("TestScene").getBytes()); + scenes = new ArrayList<>(List.of(scene)); + + SceneCollection sceneCollection = new SceneCollection(); + sceneCollection.id = 2; + sceneCollection.name = Base64.getEncoder().encodeToString(("TestSceneCollection").getBytes()); + sceneCollections = new ArrayList<>(List.of(sceneCollection)); + } + + @Test + public void sceneSunriseWeekends() { + ScheduledEvent scheduledEvent = createScheduledEventWithScene(ScheduledEvent.SCHEDULED_EVENT_TYPE_SUNRISE); + scheduledEvent.daySaturday = true; + scheduledEvent.daySunday = true; + + List scheduledEvents = new ArrayList<>(List.of(scheduledEvent)); + List channels = builder.withScenes(scenes).withScheduledEvents(scheduledEvents).build(); + + assertEquals(1, channels.size()); + assertEquals("TestScene, At sunrise, Weekends", channels.get(0).getLabel()); + } + + @Test + public void sceneSunsetWeekdays() { + ScheduledEvent scheduledEvent = createScheduledEventWithScene(ScheduledEvent.SCHEDULED_EVENT_TYPE_SUNSET); + scheduledEvent.dayMonday = true; + scheduledEvent.dayTuesday = true; + scheduledEvent.dayWednesday = true; + scheduledEvent.dayThursday = true; + scheduledEvent.dayFriday = true; + + List scheduledEvents = new ArrayList<>(List.of(scheduledEvent)); + List channels = builder.withScenes(scenes).withScheduledEvents(scheduledEvents).build(); + + assertEquals(1, channels.size()); + assertEquals("TestScene, At sunset, Weekdays", channels.get(0).getLabel()); + } + + @Test + public void sceneTimeAllDays() { + ScheduledEvent scheduledEvent = createScheduledEventWithScene(ScheduledEvent.SCHEDULED_EVENT_TYPE_TIME); + scheduledEvent.dayMonday = true; + scheduledEvent.dayTuesday = true; + scheduledEvent.dayWednesday = true; + scheduledEvent.dayThursday = true; + scheduledEvent.dayFriday = true; + scheduledEvent.daySaturday = true; + scheduledEvent.daySunday = true; + scheduledEvent.hour = 6; + scheduledEvent.minute = 30; + + List scheduledEvents = new ArrayList<>(List.of(scheduledEvent)); + List channels = builder.withScenes(scenes).withScheduledEvents(scheduledEvents).build(); + + assertEquals(1, channels.size()); + assertEquals("TestScene, 06:30, All days", channels.get(0).getLabel()); + } + + @Test + public void sceneMinutesBeforeSunriseMondayTuesday() { + ScheduledEvent scheduledEvent = createScheduledEventWithScene(ScheduledEvent.SCHEDULED_EVENT_TYPE_SUNRISE); + scheduledEvent.dayMonday = true; + scheduledEvent.dayTuesday = true; + scheduledEvent.minute = -15; + + List scheduledEvents = new ArrayList<>(List.of(scheduledEvent)); + List channels = builder.withScenes(scenes).withScheduledEvents(scheduledEvents).build(); + + assertEquals(1, channels.size()); + assertEquals("TestScene, 15m before sunrise, Mon, Tue", channels.get(0).getLabel()); + } + + @Test + public void sceneHoursMinutesAfterSunriseMonday() { + ScheduledEvent scheduledEvent = createScheduledEventWithScene(ScheduledEvent.SCHEDULED_EVENT_TYPE_SUNRISE); + scheduledEvent.dayMonday = true; + scheduledEvent.minute = 61; + + List scheduledEvents = new ArrayList<>(List.of(scheduledEvent)); + List channels = builder.withScenes(scenes).withScheduledEvents(scheduledEvents).build(); + + assertEquals(1, channels.size()); + assertEquals("TestScene, 1hr 1m after sunrise, Mon", channels.get(0).getLabel()); + } + + @Test + public void sceneMinutesBeforeSunsetWednesdayThursdayFriday() { + ScheduledEvent scheduledEvent = createScheduledEventWithScene(ScheduledEvent.SCHEDULED_EVENT_TYPE_SUNSET); + scheduledEvent.dayWednesday = true; + scheduledEvent.dayThursday = true; + scheduledEvent.dayFriday = true; + scheduledEvent.minute = -59; + + List scheduledEvents = new ArrayList<>(List.of(scheduledEvent)); + List channels = builder.withScenes(scenes).withScheduledEvents(scheduledEvents).build(); + + assertEquals(1, channels.size()); + assertEquals("TestScene, 59m before sunset, Wed, Thu, Fri", channels.get(0).getLabel()); + } + + @Test + public void sceneHourAfterSunsetFridaySaturdaySunday() { + ScheduledEvent scheduledEvent = createScheduledEventWithScene(ScheduledEvent.SCHEDULED_EVENT_TYPE_SUNSET); + scheduledEvent.dayFriday = true; + scheduledEvent.daySaturday = true; + scheduledEvent.daySunday = true; + scheduledEvent.minute = 60; + + List scheduledEvents = new ArrayList<>(List.of(scheduledEvent)); + List channels = builder.withScenes(scenes).withScheduledEvents(scheduledEvents).build(); + + assertEquals(1, channels.size()); + assertEquals("TestScene, 1hr after sunset, Fri, Sat, Sun", channels.get(0).getLabel()); + } + + @Test + public void sceneCollection() { + ScheduledEvent scheduledEvent = createScheduledEventWithSceneCollection( + ScheduledEvent.SCHEDULED_EVENT_TYPE_SUNRISE); + + List scheduledEvents = new ArrayList<>(List.of(scheduledEvent)); + List channels = builder.withSceneCollections(sceneCollections).withScheduledEvents(scheduledEvents) + .build(); + + assertEquals(1, channels.size()); + assertEquals("TestSceneCollection, At sunrise, ", channels.get(0).getLabel()); + } + + @Test + public void suppliedListIsUsed() { + ScheduledEvent scheduledEvent = createScheduledEventWithScene(ScheduledEvent.SCHEDULED_EVENT_TYPE_SUNRISE); + List scheduledEvents = new ArrayList<>(List.of(scheduledEvent)); + List existingChannels = new ArrayList<>(0); + List channels = builder.withScenes(scenes).withScheduledEvents(scheduledEvents) + .withChannels(existingChannels).build(); + + assertEquals(existingChannels, channels); + } + + @Test + public void emptyListWhenNoScheduledEvents() { + List channels = builder.build(); + + assertEquals(0, channels.size()); + } + + @Test + public void emptyListWhenNoScenesOrSceneCollections() { + ScheduledEvent scheduledEvent = createScheduledEventWithScene(ScheduledEvent.SCHEDULED_EVENT_TYPE_SUNRISE); + List scheduledEvents = new ArrayList<>(List.of(scheduledEvent)); + List channels = builder.withScheduledEvents(scheduledEvents).build(); + + assertEquals(0, channels.size()); + } + + @Test + public void emptyListWhenNoSceneForScheduledEvent() { + ScheduledEvent scheduledEvent = createScheduledEventWithSceneCollection( + ScheduledEvent.SCHEDULED_EVENT_TYPE_SUNRISE); + List scheduledEvents = new ArrayList<>(List.of(scheduledEvent)); + List channels = builder.withScenes(scenes).withScheduledEvents(scheduledEvents).build(); + + assertEquals(0, channels.size()); + } + + @Test + public void emptyListWhenNoSceneCollectionForScheduledEvent() { + ScheduledEvent scheduledEvent = createScheduledEventWithScene(ScheduledEvent.SCHEDULED_EVENT_TYPE_SUNRISE); + List scheduledEvents = new ArrayList<>(List.of(scheduledEvent)); + + List channels = builder.withSceneCollections(sceneCollections).withScheduledEvents(scheduledEvents) + .build(); + + assertEquals(0, channels.size()); + } + + @Test + public void groupAndIdAreCorrect() { + ScheduledEvent scheduledEvent = createScheduledEventWithScene(ScheduledEvent.SCHEDULED_EVENT_TYPE_SUNRISE); + scheduledEvent.id = 42; + List scheduledEvents = new ArrayList<>(List.of(scheduledEvent)); + List channels = builder.withScenes(scenes).withScheduledEvents(scheduledEvents).build(); + + assertEquals(1, channels.size()); + assertEquals(CHANNEL_GROUP_UID.getId(), channels.get(0).getUID().getGroupId()); + assertEquals(Integer.toString(scheduledEvent.id), channels.get(0).getUID().getIdWithoutGroup()); + } + + private ScheduledEvent createScheduledEventWithScene(int eventType) { + ScheduledEvent scheduledEvent = new ScheduledEvent(); + scheduledEvent.id = 1; + scheduledEvent.sceneId = scenes.get(0).id; + scheduledEvent.eventType = eventType; + return scheduledEvent; + } + + private ScheduledEvent createScheduledEventWithSceneCollection(int eventType) { + ScheduledEvent scheduledEvent = new ScheduledEvent(); + scheduledEvent.id = 1; + scheduledEvent.sceneCollectionId = sceneCollections.get(0).id; + scheduledEvent.eventType = eventType; + return scheduledEvent; + } +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/internal/HDPowerViewJUnitTests.java b/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/internal/HDPowerViewJUnitTests.java new file mode 100644 index 0000000000..b28e2cbf76 --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/internal/HDPowerViewJUnitTests.java @@ -0,0 +1,191 @@ +/** + * 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; + +import static org.junit.jupiter.api.Assertions.*; +import static org.openhab.binding.hdpowerview.internal.dto.CoordinateSystem.*; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.Objects; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.junit.jupiter.api.Test; +import org.openhab.binding.hdpowerview.internal.database.ShadeCapabilitiesDatabase; +import org.openhab.binding.hdpowerview.internal.database.ShadeCapabilitiesDatabase.Capabilities; +import org.openhab.binding.hdpowerview.internal.dto.BatteryKind; +import org.openhab.binding.hdpowerview.internal.dto.Scene; +import org.openhab.binding.hdpowerview.internal.dto.SceneCollection; +import org.openhab.binding.hdpowerview.internal.dto.ShadeData; +import org.openhab.binding.hdpowerview.internal.dto.ShadePosition; +import org.openhab.binding.hdpowerview.internal.dto.responses.SceneCollections; +import org.openhab.binding.hdpowerview.internal.dto.responses.Scenes; +import org.openhab.binding.hdpowerview.internal.dto.responses.Shades; +import org.openhab.core.library.types.PercentType; +import org.openhab.core.types.State; +import org.openhab.core.types.UnDefType; + +import com.google.gson.Gson; + +/** + * Unit tests for HD PowerView binding. + * + * @author Andrew Fiddian-Green - Initial contribution + * @author Jacob Laursen - Add support for scene groups + */ +@NonNullByDefault +public class HDPowerViewJUnitTests { + + private Gson gson = new Gson(); + + private T getObjectFromJson(String filename, Class clazz) throws IOException { + try (InputStream inputStream = HDPowerViewJUnitTests.class.getResourceAsStream(filename)) { + if (inputStream == null) { + throw new IOException("inputstream is null"); + } + byte[] bytes = inputStream.readAllBytes(); + if (bytes == null) { + throw new IOException("Resulting byte-array empty"); + } + String json = new String(bytes, StandardCharsets.UTF_8); + return Objects.requireNonNull(gson.fromJson(json, clazz)); + } + } + + /** + * Test generic JSON shades response. + */ + @Test + public void shadeNameIsDecoded() throws IOException { + Shades shades = getObjectFromJson("shades.json", Shades.class); + List shadeData = shades.shadeData; + assertNotNull(shadeData); + assertEquals(3, shadeData.size()); + ShadeData shade = shadeData.get(0); + assertEquals("Shade 2", shade.getName()); + } + + /** + * Test the BatteryKind decoding. + */ + @Test + public void testBatteryKind() throws IOException { + Shades shades = getObjectFromJson("shades.json", Shades.class); + List shadeData = shades.shadeData; + assertNotNull(shadeData); + ShadeData shade = shadeData.get(0); + assertEquals(BatteryKind.HARDWIRED_POWER_SUPPLY, shade.getBatteryKind()); + shade = shadeData.get(1); + assertEquals(BatteryKind.ERROR_UNKNOWN, shade.getBatteryKind()); + } + + /** + * Test generic JSON scene response. + */ + @Test + public void sceneNameIsDecoded() throws IOException { + Scenes scenes = getObjectFromJson("scenes.json", Scenes.class); + List sceneData = scenes.sceneData; + assertNotNull(sceneData); + assertEquals(4, sceneData.size()); + Scene scene = sceneData.get(0); + assertEquals("Door Open", scene.getName()); + } + + /** + * Test generic JSON scene collection response. + */ + @Test + public void sceneCollectionNameIsDecoded() throws IOException { + SceneCollections sceneCollections = getObjectFromJson("sceneCollections.json", SceneCollections.class); + + List sceneCollectionData = sceneCollections.sceneCollectionData; + assertNotNull(sceneCollectionData); + assertEquals(1, sceneCollectionData.size()); + + SceneCollection sceneCollection = sceneCollectionData.get(0); + assertEquals("Børn op", sceneCollection.getName()); + } + + /** + * Test the JSON parsing for a duette top down bottom up shade. + */ + @Test + public void duetteTopDownBottomUpShadeIsParsedCorrectly() throws IOException { + Shades shades = getObjectFromJson("duette.json", Shades.class); + List shadesData = shades.shadeData; + assertNotNull(shadesData); + + assertEquals(1, shadesData.size()); + ShadeData shadeData = shadesData.get(0); + assertNotNull(shadeData); + + assertEquals("Gardin 1", shadeData.getName()); + assertEquals(63778, shadeData.id); + + ShadePosition shadePos = shadeData.positions; + assertNotNull(shadePos); + + Integer capabilitiesValue = shadeData.capabilities; + assertNotNull(capabilitiesValue); + assertEquals(7, capabilitiesValue.intValue()); + ShadeCapabilitiesDatabase db = new ShadeCapabilitiesDatabase(); + Capabilities capabilities = db.getCapabilities(capabilitiesValue); + + State pos = shadePos.getState(capabilities, PRIMARY_POSITION); + assertEquals(PercentType.class, pos.getClass()); + assertEquals(59, ((PercentType) pos).intValue()); + + pos = shadePos.getState(capabilities, SECONDARY_POSITION); + assertEquals(PercentType.class, pos.getClass()); + assertEquals(35, ((PercentType) pos).intValue()); + + pos = shadePos.getState(capabilities, VANE_TILT_POSITION); + assertEquals(UnDefType.class, pos.getClass()); + + assertEquals(3, shadeData.batteryStatus); + + assertEquals(4, shadeData.signalStrength); + + assertEquals(8, shadeData.type); + + assertTrue(db.isTypeInDatabase(shadeData.type)); + assertTrue(db.isCapabilitiesInDatabase(capabilitiesValue.intValue())); + + assertEquals(db.getType(shadeData.type).getCapabilities(), capabilitiesValue.intValue()); + + assertTrue(db.getCapabilities(capabilitiesValue.intValue()).supportsSecondary()); + assertNotEquals(db.getType(shadeData.type).getCapabilities(), capabilitiesValue.intValue() + 1); + + // ==== when changing position1, position2 value is not changed (vice-versa) ==== + ShadePosition shadePosition = shadeData.positions; + assertNotNull(shadePosition); + // ==== position2 ==== + State position2Old = shadePosition.getState(capabilities, SECONDARY_POSITION); + shadePosition.setPosition(capabilities, PRIMARY_POSITION, 99); + State position2New = shadePosition.getState(capabilities, SECONDARY_POSITION); + assertEquals(PercentType.class, position2Old.getClass()); + assertEquals(PercentType.class, position2New.getClass()); + assertEquals(((PercentType) position2Old).intValue(), ((PercentType) position2New).intValue()); + + // ==== position2 ==== + State position1Old = shadePosition.getState(capabilities, PRIMARY_POSITION); + shadePosition.setPosition(capabilities, SECONDARY_POSITION, 99); + State position1New = shadePosition.getState(capabilities, PRIMARY_POSITION); + assertEquals(PercentType.class, position1Old.getClass()); + assertEquals(PercentType.class, position1New.getClass()); + assertEquals(((PercentType) position1Old).intValue(), ((PercentType) position1New).intValue()); + } +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/internal/OnlineCommunicationTest.java b/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/internal/OnlineCommunicationTest.java new file mode 100644 index 0000000000..d5415f675c --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/internal/OnlineCommunicationTest.java @@ -0,0 +1,218 @@ +/** + * 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; + +import static org.junit.jupiter.api.Assertions.*; +import static org.openhab.binding.hdpowerview.internal.dto.CoordinateSystem.*; + +import java.util.List; +import java.util.regex.Pattern; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jetty.client.HttpClient; +import org.junit.jupiter.api.Test; +import org.openhab.binding.hdpowerview.internal.database.ShadeCapabilitiesDatabase; +import org.openhab.binding.hdpowerview.internal.database.ShadeCapabilitiesDatabase.Capabilities; +import org.openhab.binding.hdpowerview.internal.dto.Scene; +import org.openhab.binding.hdpowerview.internal.dto.ShadeData; +import org.openhab.binding.hdpowerview.internal.dto.ShadePosition; +import org.openhab.binding.hdpowerview.internal.dto.responses.Scenes; +import org.openhab.binding.hdpowerview.internal.dto.responses.Shades; +import org.openhab.binding.hdpowerview.internal.exceptions.HubException; +import org.openhab.binding.hdpowerview.internal.exceptions.HubMaintenanceException; +import org.openhab.binding.hdpowerview.internal.exceptions.HubProcessingException; +import org.openhab.core.library.types.PercentType; +import org.openhab.core.types.State; + +/** + * Unit tests for HD PowerView binding. + * + * @author Andrew Fiddian-Green - Initial contribution + */ +@NonNullByDefault +public class OnlineCommunicationTest { + + private static final Pattern VALID_IP_V4_ADDRESS = Pattern + .compile("\\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\\.|$)){4}\\b"); + + /** + * Run a series of ONLINE tests on the communication with a hub. + * + * @param hubIPAddress must be a valid hub IP address to run the + * tests on; or an INVALID IP address to + * suppress the tests + * @param allowShadeMovementCommands set to true if you accept that the tests + * shall physically move the shades + */ + @Test + public void testOnlineCommunication() { + /* + * NOTE: in order to actually run these tests you must have a hub physically + * available, and its IP address must be correctly configured in the + * "hubIPAddress" string constant e.g. "192.168.1.123" + */ + String hubIPAddress = "192.168.1.xxx"; + + /* + * NOTE: set allowShadeMovementCommands = true if you accept physically moving + * the shades during these tests + */ + boolean allowShadeMovementCommands = false; + + if (VALID_IP_V4_ADDRESS.matcher(hubIPAddress).matches()) { + // ==== initialize stuff ==== + HttpClient client = new HttpClient(); + assertNotNull(client); + + // ==== start the client ==== + try { + client.start(); + assertTrue(client.isStarted()); + } catch (Exception e) { + fail(e.getMessage()); + } + + HDPowerViewWebTargets webTargets = new HDPowerViewWebTargets(client, hubIPAddress); + assertNotNull(webTargets); + + int shadeId = 0; + ShadePosition shadePos = null; + Shades shadesX = null; + + // ==== get all shades ==== + try { + shadesX = webTargets.getShades(); + assertNotNull(shadesX); + List shadesData = shadesX.shadeData; + assertNotNull(shadesData); + + assertTrue(!shadesData.isEmpty()); + ShadeData shadeData; + shadeData = shadesData.get(0); + assertNotNull(shadeData); + assertTrue(shadeData.getName().length() > 0); + shadePos = shadeData.positions; + assertNotNull(shadePos); + ShadeData shadeZero = shadesData.get(0); + assertNotNull(shadeZero); + shadeId = shadeZero.id; + assertNotEquals(0, shadeId); + + for (ShadeData shadexData : shadesData) { + String shadeName = shadexData.getName(); + assertNotNull(shadeName); + } + } catch (HubException e) { + fail(e.getMessage()); + } + + // ==== get all scenes ==== + int sceneId = 0; + try { + Scenes scenes = webTargets.getScenes(); + assertNotNull(scenes); + + List scenesData = scenes.sceneData; + assertNotNull(scenesData); + + assertTrue(!scenesData.isEmpty()); + Scene sceneZero = scenesData.get(0); + assertNotNull(sceneZero); + sceneId = sceneZero.id; + assertTrue(sceneId > 0); + + for (Scene scene : scenesData) { + String sceneName = scene.getName(); + assertNotNull(sceneName); + } + } catch (HubException e) { + fail(e.getMessage()); + } + + // ==== refresh a specific shade ==== + ShadeData shadeData = null; + try { + assertNotEquals(0, shadeId); + shadeData = webTargets.refreshShadePosition(shadeId); + } catch (HubException e) { + fail(e.getMessage()); + } + + // ==== move a specific shade ==== + try { + assertNotEquals(0, shadeId); + + if (shadeData != null) { + ShadePosition positions = shadeData.positions; + assertNotNull(positions); + Integer capabilitiesValue = shadeData.capabilities; + assertNotNull(capabilitiesValue); + + Capabilities capabilities = new ShadeCapabilitiesDatabase() + .getCapabilities(capabilitiesValue.intValue()); + + State pos = positions.getState(capabilities, PRIMARY_POSITION); + assertEquals(PercentType.class, pos.getClass()); + + int position = ((PercentType) pos).intValue(); + position = position + ((position <= 10) ? 5 : -5); + + ShadePosition targetPosition = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, + position); + assertNotNull(targetPosition); + + if (allowShadeMovementCommands) { + webTargets.moveShade(shadeId, targetPosition); + + ShadeData newData = webTargets.getShade(shadeId); + ShadePosition actualPosition = newData.positions; + assertNotNull(actualPosition); + assertEquals(targetPosition.getState(capabilities, PRIMARY_POSITION), + actualPosition.getState(capabilities, PRIMARY_POSITION)); + } + } + } catch (HubException e) { + fail(e.getMessage()); + } + + // ==== activate a specific scene ==== + if (allowShadeMovementCommands) { + try { + assertNotNull(sceneId); + webTargets.activateScene(sceneId); + } catch (HubProcessingException | HubMaintenanceException e) { + fail(e.getMessage()); + } + } + + // ==== test stop command ==== + if (allowShadeMovementCommands) { + try { + assertNotNull(sceneId); + webTargets.stopShade(shadeId); + } catch (HubException e) { + fail(e.getMessage()); + } + } + + // ==== stop the client ==== + if (client.isRunning()) { + try { + client.stop(); + } catch (Exception e) { + fail(e.getMessage()); + } + } + } + } +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/internal/SceneChannelBuilderTest.java b/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/internal/SceneChannelBuilderTest.java new file mode 100644 index 0000000000..4d6be154a4 --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/internal/SceneChannelBuilderTest.java @@ -0,0 +1,116 @@ +/** + * 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; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.mock; + +import java.util.ArrayList; +import java.util.Base64; +import java.util.List; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.openhab.binding.hdpowerview.internal.builders.SceneChannelBuilder; +import org.openhab.binding.hdpowerview.internal.dto.Scene; +import org.openhab.binding.hdpowerview.internal.providers.MockedLocaleProvider; +import org.openhab.binding.hdpowerview.internal.providers.MockedTranslationProvider; +import org.openhab.core.thing.Channel; +import org.openhab.core.thing.ChannelGroupUID; +import org.openhab.core.thing.ThingUID; +import org.openhab.core.thing.type.AutoUpdatePolicy; +import org.osgi.framework.Bundle; + +/** + * Unit tests for {@link SceneChannelBuilder}. + * + * @author Jacob Laursen - Initial contribution + */ +@NonNullByDefault +public class SceneChannelBuilderTest { + + private static final ChannelGroupUID CHANNEL_GROUP_UID = new ChannelGroupUID( + new ThingUID(HDPowerViewBindingConstants.BINDING_ID, SceneChannelBuilderTest.class.getSimpleName()), + HDPowerViewBindingConstants.CHANNELTYPE_SCENE_ACTIVATE); + + private static final HDPowerViewTranslationProvider TRANSLATION_PROVIDER = new HDPowerViewTranslationProvider( + mock(Bundle.class), new MockedTranslationProvider(), new MockedLocaleProvider()); + + private SceneChannelBuilder builder = SceneChannelBuilder.create(TRANSLATION_PROVIDER, CHANNEL_GROUP_UID); + + @BeforeEach + private void setUp() { + builder = SceneChannelBuilder.create(TRANSLATION_PROVIDER, CHANNEL_GROUP_UID); + } + + @Test + public void labelIsCorrect() { + List scenes = createScenes(); + List channels = builder.withScenes(scenes).build(); + + assertEquals(1, channels.size()); + assertEquals("TestScene", channels.get(0).getLabel()); + } + + @Test + public void descriptionIsCorrect() { + List scenes = createScenes(); + List channels = builder.withScenes(scenes).build(); + + assertEquals(1, channels.size()); + assertEquals("Activates the scene 'TestScene'", channels.get(0).getDescription()); + } + + @Test + public void groupAndIdAreCorrect() { + List scenes = createScenes(); + List channels = builder.withScenes(scenes).build(); + + assertEquals(1, channels.size()); + assertEquals(CHANNEL_GROUP_UID.getId(), channels.get(0).getUID().getGroupId()); + assertEquals(Integer.toString(scenes.get(0).id), channels.get(0).getUID().getIdWithoutGroup()); + } + + @Test + public void autoUpdatePolicyIsCorrect() { + List scenes = createScenes(); + List channels = builder.withScenes(scenes).build(); + + assertEquals(1, channels.size()); + assertEquals(AutoUpdatePolicy.VETO, channels.get(0).getAutoUpdatePolicy()); + } + + @Test + public void suppliedListIsUsed() { + List scenes = createScenes(); + List existingChannels = new ArrayList<>(0); + List channels = builder.withScenes(scenes).withChannels(existingChannels).build(); + + assertEquals(existingChannels, channels); + } + + @Test + public void emptyListWhenNoScenes() { + List channels = builder.build(); + + assertEquals(0, channels.size()); + } + + private List createScenes() { + Scene scene = new Scene(); + scene.id = 1; + scene.name = Base64.getEncoder().encodeToString(("TestScene").getBytes()); + return new ArrayList<>(List.of(scene)); + } +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/internal/SceneGroupChannelBuilderTest.java b/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/internal/SceneGroupChannelBuilderTest.java new file mode 100644 index 0000000000..fc1344ea85 --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/internal/SceneGroupChannelBuilderTest.java @@ -0,0 +1,116 @@ +/** + * 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; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.mock; + +import java.util.ArrayList; +import java.util.Base64; +import java.util.List; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.openhab.binding.hdpowerview.internal.builders.SceneGroupChannelBuilder; +import org.openhab.binding.hdpowerview.internal.dto.SceneCollection; +import org.openhab.binding.hdpowerview.internal.providers.MockedLocaleProvider; +import org.openhab.binding.hdpowerview.internal.providers.MockedTranslationProvider; +import org.openhab.core.thing.Channel; +import org.openhab.core.thing.ChannelGroupUID; +import org.openhab.core.thing.ThingUID; +import org.openhab.core.thing.type.AutoUpdatePolicy; +import org.osgi.framework.Bundle; + +/** + * Unit tests for {@link SceneGroupChannelBuilder}. + * + * @author Jacob Laursen - Initial contribution + */ +@NonNullByDefault +public class SceneGroupChannelBuilderTest { + + private static final ChannelGroupUID CHANNEL_GROUP_UID = new ChannelGroupUID( + new ThingUID(HDPowerViewBindingConstants.BINDING_ID, SceneGroupChannelBuilderTest.class.getSimpleName()), + HDPowerViewBindingConstants.CHANNELTYPE_SCENE_GROUP_ACTIVATE); + + private static final HDPowerViewTranslationProvider TRANSLATION_PROVIDER = new HDPowerViewTranslationProvider( + mock(Bundle.class), new MockedTranslationProvider(), new MockedLocaleProvider()); + + private SceneGroupChannelBuilder builder = SceneGroupChannelBuilder.create(TRANSLATION_PROVIDER, CHANNEL_GROUP_UID); + + @BeforeEach + private void setUp() { + builder = SceneGroupChannelBuilder.create(TRANSLATION_PROVIDER, CHANNEL_GROUP_UID); + } + + @Test + public void labelIsCorrect() { + List sceneCollections = createSceneCollections(); + List channels = builder.withSceneCollections(sceneCollections).build(); + + assertEquals(1, channels.size()); + assertEquals("TestSceneCollection", channels.get(0).getLabel()); + } + + @Test + public void descriptionIsCorrect() { + List sceneCollections = createSceneCollections(); + List channels = builder.withSceneCollections(sceneCollections).build(); + + assertEquals(1, channels.size()); + assertEquals("Activates the scene group 'TestSceneCollection'", channels.get(0).getDescription()); + } + + @Test + public void groupAndIdAreCorrect() { + List sceneCollections = createSceneCollections(); + List channels = builder.withSceneCollections(sceneCollections).build(); + + assertEquals(1, channels.size()); + assertEquals(CHANNEL_GROUP_UID.getId(), channels.get(0).getUID().getGroupId()); + assertEquals(Integer.toString(sceneCollections.get(0).id), channels.get(0).getUID().getIdWithoutGroup()); + } + + @Test + public void autoUpdatePolicyIsCorrect() { + List sceneCollections = createSceneCollections(); + List channels = builder.withSceneCollections(sceneCollections).build(); + + assertEquals(1, channels.size()); + assertEquals(AutoUpdatePolicy.VETO, channels.get(0).getAutoUpdatePolicy()); + } + + @Test + public void suppliedListIsUsed() { + List sceneCollections = createSceneCollections(); + List existingChannels = new ArrayList<>(0); + List channels = builder.withSceneCollections(sceneCollections).withChannels(existingChannels).build(); + + assertEquals(existingChannels, channels); + } + + @Test + public void emptyListWhenNoSceneCollections() { + List channels = builder.build(); + + assertEquals(0, channels.size()); + } + + private List createSceneCollections() { + SceneCollection sceneCollection = new SceneCollection(); + sceneCollection.id = 1; + sceneCollection.name = Base64.getEncoder().encodeToString(("TestSceneCollection").getBytes()); + return new ArrayList<>(List.of(sceneCollection)); + } +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/internal/ShadePositionTest.java b/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/internal/ShadePositionTest.java new file mode 100644 index 0000000000..5ced717f20 --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/internal/ShadePositionTest.java @@ -0,0 +1,461 @@ +/** + * 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; + +import static org.junit.jupiter.api.Assertions.*; +import static org.openhab.binding.hdpowerview.internal.dto.CoordinateSystem.*; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.junit.jupiter.api.Test; +import org.openhab.binding.hdpowerview.internal.database.ShadeCapabilitiesDatabase; +import org.openhab.binding.hdpowerview.internal.database.ShadeCapabilitiesDatabase.Capabilities; +import org.openhab.binding.hdpowerview.internal.dto.ShadePosition; +import org.openhab.core.library.types.PercentType; +import org.openhab.core.types.State; +import org.openhab.core.types.UnDefType; + +/** + * Unit tests for Shade Position setting and getting. + * + * @author Andrew Fiddian-Green - Initial contribution + */ +@NonNullByDefault +public class ShadePositionTest { + + private final ShadeCapabilitiesDatabase db = new ShadeCapabilitiesDatabase(); + + /** + * General tests of the database of known types. + */ + @Test + public void testKnownTypesDatabase() { + assertTrue(db.isTypeInDatabase(4)); + assertTrue(db.isCapabilitiesInDatabase(0)); + assertTrue(db.isCapabilitiesInDatabase(10)); + + assertTrue(db.getCapabilities(0).supportsPrimary()); + assertTrue(db.getCapabilities(1).supportsTiltOnClosed()); + assertTrue(db.getCapabilities(2).supportsTilt180()); + assertTrue(db.getCapabilities(2).supportsTiltAnywhere()); + assertTrue(db.getCapabilities(4).supportsTilt180()); + assertTrue(db.getCapabilities(4).supportsTiltAnywhere()); + assertTrue(db.getCapabilities(5).supportsTilt180()); + assertFalse(db.getCapabilities(5).supportsPrimary()); + assertTrue(db.getCapabilities(6).isPrimaryInverted()); + assertTrue(db.getCapabilities(7).supportsSecondary()); + assertTrue(db.getCapabilities(8).supportsSecondaryOverlapped()); + assertTrue(db.getCapabilities(9).supportsSecondaryOverlapped()); + assertTrue(db.getCapabilities(9).supportsTiltOnClosed()); + + assertEquals(db.getType(4).getCapabilities(), 0); + assertEquals(db.getType(-1).getCapabilities(), -1); + + assertFalse(db.isTypeInDatabase(99)); + assertFalse(db.isCapabilitiesInDatabase(99)); + + assertFalse(db.getCapabilities(0).isPrimaryInverted()); + assertFalse(db.getCapabilities(-1).isPrimaryInverted()); + assertFalse(db.getCapabilities(99).isPrimaryInverted()); + + assertFalse(db.getCapabilities(0).supportsSecondary()); + assertFalse(db.getCapabilities(-1).supportsSecondary()); + assertFalse(db.getCapabilities(99).supportsSecondary()); + } + + /** + * Helper method; test if shade position is a PercentType and that its value is correct. + * + * @param position the shade position + * @param value the test value to compare with + */ + private void assertShadePosition(State position, int value) { + assertEquals(PercentType.class, position.getClass()); + assertEquals(value, ((PercentType) position).intValue()); + } + + /** + * Test parsing of Capabilities 1 ShadePosition (shade fully up). + * + */ + @Test + public void testCaps1ShadePositionParsingFullyUp() { + Capabilities capabilities = db.getCapabilities(1); + ShadePosition test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 0); + assertNotNull(test); + assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 0); + assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), UnDefType.UNDEF); + assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF); + } + + /** + * Test parsing of Capabilities 1 ShadePosition (shade fully down (method 1)). + * + */ + @Test + public void testCaps1ShadePositionParsingShadeFullyDown1() { + Capabilities capabilities = db.getCapabilities(1); + ShadePosition test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 100); + assertNotNull(test); + assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100); + assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), UnDefType.UNDEF); + assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 0); + } + + /** + * Test parsing of Capabilities 1 ShadePosition (shade fully down (method 2)). + * + */ + @Test + public void testCaps1ShadePositionParsingShadeFullyDown2() { + Capabilities capabilities = db.getCapabilities(1); + ShadePosition test = new ShadePosition().setPosition(capabilities, VANE_TILT_POSITION, 0); + assertNotNull(test); + assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100); + assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), UnDefType.UNDEF); + assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 0); + } + + /** + * Test parsing of Capabilities 1 ShadePosition (shade fully down (method 2) and vane fully open). + * + */ + @Test + public void testCaps1ShadePositionParsingShadeFullyDownVaneOpen() { + Capabilities capabilities = db.getCapabilities(1); + ShadePosition test = new ShadePosition().setPosition(capabilities, VANE_TILT_POSITION, 88); + assertNotNull(test); + assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100); + assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), UnDefType.UNDEF); + assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 88); + } + + /** + * On dual rail shades, it should not be possible to drive the upper rail below the lower rail, or vice-versa. So + * the binding code applies constraints on setting such positions. This test checks that the constraint code is + * working. + */ + @Test + public void testDualRailConstraints() { + Capabilities capabilities = db.getCapabilities(7); + ShadePosition test = new ShadePosition(); + + // ==== OK !! primary at bottom, secondary at top ==== + test.setPosition(capabilities, PRIMARY_POSITION, 100).setPosition(capabilities, SECONDARY_POSITION, 0); + assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100); + assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0); + assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF); + + // ==== OK !! primary at middle, secondary at top ==== + test.setPosition(capabilities, PRIMARY_POSITION, 50).setPosition(capabilities, SECONDARY_POSITION, 0); + assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 50); + assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0); + assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF); + + // ==== OK !! primary at middle, secondary at middle ==== + test.setPosition(capabilities, PRIMARY_POSITION, 50).setPosition(capabilities, SECONDARY_POSITION, 50); + assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 50); + assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 50); + assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF); + + // ==== IMPOSSIBLE !! secondary at middle, primary above => test the constraining code ==== + test.setPosition(capabilities, SECONDARY_POSITION, 0).setPosition(capabilities, PRIMARY_POSITION, 100); + test.setPosition(capabilities, SECONDARY_POSITION, 40).setPosition(capabilities, PRIMARY_POSITION, 25); + assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 40); + assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 40); + assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF); + + // ==== OK !! secondary at middle, primary below ==== + test.setPosition(capabilities, SECONDARY_POSITION, 0).setPosition(capabilities, PRIMARY_POSITION, 100); + test.setPosition(capabilities, SECONDARY_POSITION, 50).setPosition(capabilities, PRIMARY_POSITION, 75); + assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 75); + assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 50); + assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF); + + // ==== IMPOSSIBLE !! primary at middle, secondary below => test the constraining code ==== + test.setPosition(capabilities, SECONDARY_POSITION, 0).setPosition(capabilities, PRIMARY_POSITION, 100); + test.setPosition(capabilities, PRIMARY_POSITION, 60).setPosition(capabilities, SECONDARY_POSITION, 75); + assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 60); + assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 60); + assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF); + + // ==== OK !! primary at middle, secondary above ==== + test.setPosition(capabilities, SECONDARY_POSITION, 0).setPosition(capabilities, PRIMARY_POSITION, 100); + test.setPosition(capabilities, PRIMARY_POSITION, 60).setPosition(capabilities, SECONDARY_POSITION, 25); + assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 60); + assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 25); + assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF); + } + + /** + * Test parsing of DuoLite shades having a secondary blackout shade. + * + */ + @Test + public void testDuoliteShadePositionParsing() { + // blackout shades have capabilities 8 + Capabilities capabilities = db.getCapabilities(8); + ShadePosition test; + + // both shades up + test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 0); + assertNotNull(test); + assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 0); + assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0); + assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF); + + // front shade 50% down + test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 50); + assertNotNull(test); + assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 50); + assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0); + assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF); + + // front shade 100% down, back shade 0% down + test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 100); + assertNotNull(test); + assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100); + assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0); + assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF); + + // front shade 100% down, back shade 0% down (ALTERNATE) + test = new ShadePosition().setPosition(capabilities, SECONDARY_POSITION, 0); + assertNotNull(test); + assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100); + assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0); + assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF); + + // front shade 100% down, back shade 50% down + test = new ShadePosition().setPosition(capabilities, SECONDARY_POSITION, 50); + assertNotNull(test); + assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100); + assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 50); + assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF); + + // front shade 100% down, back shade 100% down + test = new ShadePosition().setPosition(capabilities, SECONDARY_POSITION, 100); + assertNotNull(test); + assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100); + assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 100); + assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF); + } + + /** + * Test parsing of DuoLite shades having both a secondary blackout shade, and tilt functionality. + * + */ + @Test + public void testDuoliteTiltShadePositionParsing() { + // blackout shades with tilt have capabilities 9 + Capabilities capabilities = db.getCapabilities(9); + ShadePosition test; + + // front shade up + test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 0); + assertNotNull(test); + assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 0); + assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0); + assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF); + + // front shade 30% down + test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 30); + assertNotNull(test); + assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 30); + assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0); + assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF); + + // front shade 100% down + test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 100); + assertNotNull(test); + assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100); + assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0); + assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 0); + + // tilt 0% + test = new ShadePosition().setPosition(capabilities, VANE_TILT_POSITION, 0); + assertNotNull(test); + assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100); + assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0); + assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 0); + + // tilt 30% + test = new ShadePosition().setPosition(capabilities, VANE_TILT_POSITION, 30); + assertNotNull(test); + assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100); + assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0); + assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 30); + + // tilt 100% + test = new ShadePosition().setPosition(capabilities, VANE_TILT_POSITION, 100); + assertNotNull(test); + assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100); + assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0); + assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 100); + + // back shade 0% down + test = new ShadePosition().setPosition(capabilities, SECONDARY_POSITION, 0); + assertNotNull(test); + assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100); + assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0); + assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 100); + + // back shade 30% down + test = new ShadePosition().setPosition(capabilities, SECONDARY_POSITION, 30); + assertNotNull(test); + assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100); + assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 30); + assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 100); + + // back shade 100% down + test = new ShadePosition().setPosition(capabilities, SECONDARY_POSITION, 100); + assertNotNull(test); + assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100); + assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 100); + assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 100); + + // test constraints on impossible values: primary 30% => tilt 30% + test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 30).setPosition(capabilities, + VANE_TILT_POSITION, 30); + assertNotNull(test); + assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100); + assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0); + assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 30); + + // test constraints on impossible values: primary 30% => tilt 30% => back shade 30% down + test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 30) + .setPosition(capabilities, VANE_TILT_POSITION, 30).setPosition(capabilities, SECONDARY_POSITION, 30); + assertNotNull(test); + assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100); + assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 30); + assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 100); + } + + /** + * Test parsing of Capabilities 0 ShadePosition (shade fully up). + * + */ + @Test + public void testCaps0ShadePositionParsingFullyUp() { + Capabilities capabilities = db.getCapabilities(0); + ShadePosition test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 0); + assertNotNull(test); + assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 0); + assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), UnDefType.UNDEF); + assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF); + } + + /** + * Test parsing of Capabilities 0 ShadePosition (shade fully down). + * + */ + @Test + public void testCap0ShadePositionParsingShadeFullyDown() { + Capabilities capabilities = db.getCapabilities(0); + ShadePosition test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 100); + assertNotNull(test); + assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100); + assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), UnDefType.UNDEF); + assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF); + } + + /** + * Helper method; test if shade State is correct. + * + * @param actual the shade State + * @param target the test value to compare with + */ + private void assertShadePosition(State actual, State target) { + assertTrue(target.equals(actual)); + } + + /** + * Test parsing of Type 44 ShadePosition (shade fully up). + * + */ + @Test + public void testType44ShadePositionParsingFullyUp() { + Capabilities capabilities = db.getCapabilities(44, null); + ShadePosition test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 0); + assertNotNull(test); + assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 0); + assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), UnDefType.UNDEF); + assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF); + } + + /** + * Test parsing of Type 44 ShadePosition (shade fully down (method 2) and vane fully open). + * + */ + @Test + public void testType44ShadePositionParsingShadeFullyDownVaneOpen() { + Capabilities capabilities = db.getCapabilities(44, null); + ShadePosition test = new ShadePosition().setPosition(capabilities, VANE_TILT_POSITION, 88); + assertNotNull(test); + assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100); + assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), UnDefType.UNDEF); + assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 88); + } + + /** + * Test the getCapabilities functionality. + */ + @Test + public void testGetCapabilities() { + Capabilities caps; + /* + * - type not in database + * - null external capabilities + * => return default (0) + */ + caps = db.getCapabilities(0, null); + assertEquals(0, caps.getValue()); + /* + * - type not in database + * - valid external capabilities (1) + * => return external capabilities (1) + */ + caps = db.getCapabilities(0, 1); + assertEquals(1, caps.getValue()); + /* + * - type not in database + * - external capabilities not in database (99) + * => return default (0) + */ + caps = db.getCapabilities(0, 99); + assertEquals(0, caps.getValue()); + /* + * - type 62 in database + * - inherent capabilities (2) + * - null external capabilities + * => return inherent capabilities (2) + */ + caps = db.getCapabilities(62, null); + assertEquals(2, caps.getValue()); + /* + * - type 62 in database + * - inherent capabilities (2) + * - non matching external capabilities (1) + * => return external capabilities (1) + */ + caps = db.getCapabilities(62, 1); + assertEquals(1, caps.getValue()); + /* + * - type 44 in database + * - inherent capabilities (0) + * - with capabilitiesOverride (1) + * - non matching external capabilities (2) + * => return capabilitiesOverride (1) + */ + caps = db.getCapabilities(44, 2); + assertEquals(1, caps.getValue()); + } +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/internal/providers/MockedLocaleProvider.java b/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/internal/providers/MockedLocaleProvider.java new file mode 100644 index 0000000000..d95879f454 --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/internal/providers/MockedLocaleProvider.java @@ -0,0 +1,30 @@ +/** + * 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.providers; + +import java.util.Locale; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.core.i18n.LocaleProvider; + +/** + * Locale provider for unit tests. + * + * @author Jacob Laursen - Initial contribution + */ +@NonNullByDefault +public class MockedLocaleProvider implements LocaleProvider { + public Locale getLocale() { + return Locale.ENGLISH; + } +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/internal/providers/MockedTranslationProvider.java b/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/internal/providers/MockedTranslationProvider.java new file mode 100644 index 0000000000..9c9503ef1e --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/internal/providers/MockedTranslationProvider.java @@ -0,0 +1,66 @@ +/** + * 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.providers; + +import static java.util.Map.entry; + +import java.text.MessageFormat; +import java.util.Locale; +import java.util.Map; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.openhab.core.i18n.TranslationProvider; +import org.osgi.framework.Bundle; + +/** + * Translation provider for unit tests. + * + * @author Jacob Laursen - Initial contribution + */ +@NonNullByDefault +public class MockedTranslationProvider implements TranslationProvider { + + private static final Map TEXTS = Map.ofEntries( + entry("dynamic-channel.scene-activate.description", "Activates the scene ''{0}''"), + entry("dynamic-channel.scene-group-activate.description", "Activates the scene group ''{0}''"), + entry("dynamic-channel.automation-enabled.description", "Enables/disables the automation ''{0}''"), + entry("dynamic-channel.automation-enabled.label", "{0}, {1}, {2}"), + entry("dynamic-channel.automation.hour", "{0}hr"), entry("dynamic-channel.automation.minute", "{0}m"), + entry("dynamic-channel.automation.hour-minute", "{0}hr {1}m"), + entry("dynamic-channel.automation.at-sunrise", "At sunrise"), + entry("dynamic-channel.automation.before-sunrise", "{0} before sunrise"), + entry("dynamic-channel.automation.after-sunrise", "{0} after sunrise"), + entry("dynamic-channel.automation.at-sunset", "At sunset"), + entry("dynamic-channel.automation.before-sunset", "{0} before sunset"), + entry("dynamic-channel.automation.after-sunset", "{0} after sunset"), + entry("dynamic-channel.automation.weekdays", "Weekdays"), + entry("dynamic-channel.automation.weekends", "Weekends"), + entry("dynamic-channel.automation.all-days", "All days")); + + public MockedTranslationProvider() { + } + + @Nullable + public String getText(@Nullable Bundle bundle, @Nullable String key, @Nullable String defaultText, + @Nullable Locale locale) { + return ""; + } + + @Nullable + public String getText(@Nullable Bundle bundle, @Nullable String key, @Nullable String defaultText, + @Nullable Locale locale, @Nullable Object @Nullable... arguments) { + String text = TEXTS.get(key); + return MessageFormat.format(text != null ? text : key, arguments); + } +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/providers/MockedLocaleProvider.java b/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/providers/MockedLocaleProvider.java deleted file mode 100644 index 8161cc8e28..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/providers/MockedLocaleProvider.java +++ /dev/null @@ -1,30 +0,0 @@ -/** - * 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.providers; - -import java.util.Locale; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.openhab.core.i18n.LocaleProvider; - -/** - * Locale provider for unit tests. - * - * @author Jacob Laursen - Initial contribution - */ -@NonNullByDefault -public class MockedLocaleProvider implements LocaleProvider { - public Locale getLocale() { - return Locale.ENGLISH; - } -} diff --git a/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/providers/MockedTranslationProvider.java b/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/providers/MockedTranslationProvider.java deleted file mode 100644 index da7152ad75..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/test/java/org/openhab/binding/hdpowerview/providers/MockedTranslationProvider.java +++ /dev/null @@ -1,66 +0,0 @@ -/** - * 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.providers; - -import static java.util.Map.entry; - -import java.text.MessageFormat; -import java.util.Locale; -import java.util.Map; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.eclipse.jdt.annotation.Nullable; -import org.openhab.core.i18n.TranslationProvider; -import org.osgi.framework.Bundle; - -/** - * Translation provider for unit tests. - * - * @author Jacob Laursen - Initial contribution - */ -@NonNullByDefault -public class MockedTranslationProvider implements TranslationProvider { - - private static final Map TEXTS = Map.ofEntries( - entry("dynamic-channel.scene-activate.description", "Activates the scene ''{0}''"), - entry("dynamic-channel.scene-group-activate.description", "Activates the scene group ''{0}''"), - entry("dynamic-channel.automation-enabled.description", "Enables/disables the automation ''{0}''"), - entry("dynamic-channel.automation-enabled.label", "{0}, {1}, {2}"), - entry("dynamic-channel.automation.hour", "{0}hr"), entry("dynamic-channel.automation.minute", "{0}m"), - entry("dynamic-channel.automation.hour-minute", "{0}hr {1}m"), - entry("dynamic-channel.automation.at-sunrise", "At sunrise"), - entry("dynamic-channel.automation.before-sunrise", "{0} before sunrise"), - entry("dynamic-channel.automation.after-sunrise", "{0} after sunrise"), - entry("dynamic-channel.automation.at-sunset", "At sunset"), - entry("dynamic-channel.automation.before-sunset", "{0} before sunset"), - entry("dynamic-channel.automation.after-sunset", "{0} after sunset"), - entry("dynamic-channel.automation.weekdays", "Weekdays"), - entry("dynamic-channel.automation.weekends", "Weekends"), - entry("dynamic-channel.automation.all-days", "All days")); - - public MockedTranslationProvider() { - } - - @Nullable - public String getText(@Nullable Bundle bundle, @Nullable String key, @Nullable String defaultText, - @Nullable Locale locale) { - return ""; - } - - @Nullable - public String getText(@Nullable Bundle bundle, @Nullable String key, @Nullable String defaultText, - @Nullable Locale locale, @Nullable Object @Nullable... arguments) { - String text = TEXTS.get(key); - return MessageFormat.format(text != null ? text : key, arguments); - } -} diff --git a/bundles/org.openhab.binding.hdpowerview/src/test/resources/org/openhab/binding/hdpowerview/duette.json b/bundles/org.openhab.binding.hdpowerview/src/test/resources/org/openhab/binding/hdpowerview/duette.json deleted file mode 100644 index ff4e03e01c..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/test/resources/org/openhab/binding/hdpowerview/duette.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "shadeIds": [ - 63778 - ], - "shadeData": [ - { - "id": 63778, - "type": 8, - "batteryStatus": 3, - "batteryStrength": 168, - "roomId": 891, - "firmware": { - "revision": 1, - "subRevision": 8, - "build": 1944 - }, - "motor": { - "revision": 0, - "subRevision": 0, - "build": 267 - }, - "name": "R2FyZGluIDE=", - "groupId": 18108, - "positions": { - "posKind2": 2, - "position2": 23194, - "posKind1": 1, - "position1": 26566 - }, - "signalStrength": 4, - "aid": 2, - "capabilities": 7, - "batteryKind": "unassigned" - } - ] -} diff --git a/bundles/org.openhab.binding.hdpowerview/src/test/resources/org/openhab/binding/hdpowerview/internal/duette.json b/bundles/org.openhab.binding.hdpowerview/src/test/resources/org/openhab/binding/hdpowerview/internal/duette.json new file mode 100644 index 0000000000..ff4e03e01c --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/test/resources/org/openhab/binding/hdpowerview/internal/duette.json @@ -0,0 +1,36 @@ +{ + "shadeIds": [ + 63778 + ], + "shadeData": [ + { + "id": 63778, + "type": 8, + "batteryStatus": 3, + "batteryStrength": 168, + "roomId": 891, + "firmware": { + "revision": 1, + "subRevision": 8, + "build": 1944 + }, + "motor": { + "revision": 0, + "subRevision": 0, + "build": 267 + }, + "name": "R2FyZGluIDE=", + "groupId": 18108, + "positions": { + "posKind2": 2, + "position2": 23194, + "posKind1": 1, + "position1": 26566 + }, + "signalStrength": 4, + "aid": 2, + "capabilities": 7, + "batteryKind": "unassigned" + } + ] +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/test/resources/org/openhab/binding/hdpowerview/internal/sceneCollections.json b/bundles/org.openhab.binding.hdpowerview/src/test/resources/org/openhab/binding/hdpowerview/internal/sceneCollections.json new file mode 100644 index 0000000000..7631f89077 --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/test/resources/org/openhab/binding/hdpowerview/internal/sceneCollections.json @@ -0,0 +1,15 @@ +{ + "sceneCollectionIds": [ + 27119 + ], + "sceneCollectionData": [ + { + "name": "QsO4cm4gb3A=", + "colorId": 12, + "iconId": 17, + "id": 27119, + "order": 0, + "hkAssist": false + } + ] +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/test/resources/org/openhab/binding/hdpowerview/internal/scenes.json b/bundles/org.openhab.binding.hdpowerview/src/test/resources/org/openhab/binding/hdpowerview/internal/scenes.json new file mode 100644 index 0000000000..4cbe0a4339 --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/test/resources/org/openhab/binding/hdpowerview/internal/scenes.json @@ -0,0 +1,50 @@ +{ + "sceneIds": [ + 18097, + 22663, + 35821, + 6551 + ], + "sceneData": [ + { + "roomId": 59611, + "name": "RG9vciBPcGVu", + "colorId": 6, + "iconId": 160, + "networkNumber": 19, + "id": 18097, + "order": 3, + "hkAssist": false + }, + { + "roomId": 59611, + "name": "SGVhcnQ=", + "colorId": 15, + "iconId": 49, + "networkNumber": 3, + "id": 22663, + "order": 0, + "hkAssist": false + }, + { + "roomId": 59611, + "name": "Q2xvc2U=", + "colorId": 5, + "iconId": 31, + "networkNumber": 8, + "id": 35821, + "order": 2, + "hkAssist": false + }, + { + "roomId": 59611, + "name": "T3Blbg==", + "colorId": 10, + "iconId": 95, + "networkNumber": 20, + "id": 6551, + "order": 1, + "hkAssist": false + } + ] +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/test/resources/org/openhab/binding/hdpowerview/internal/shades.json b/bundles/org.openhab.binding.hdpowerview/src/test/resources/org/openhab/binding/hdpowerview/internal/shades.json new file mode 100644 index 0000000000..cfbf435087 --- /dev/null +++ b/bundles/org.openhab.binding.hdpowerview/src/test/resources/org/openhab/binding/hdpowerview/internal/shades.json @@ -0,0 +1,90 @@ +{ + "shadeIds": [ + 25206, + 55854, + 50150 + ], + "shadeData": [ + { + "id": 25206, + "type": 44, + "batteryStatus": 3, + "batteryStrength": 179, + "roomId": 59611, + "firmware": { + "revision": 1, + "subRevision": 8, + "build": 1944 + }, + "name": "U2hhZGUgMg==", + "motor": { + "revision": 51, + "subRevision": 51, + "build": 11825 + }, + "groupId": 64003, + "aid": 2, + "signalStrength": 4, + "capabilities": 0, + "batteryKind": 1, + "positions": { + "posKind1": 3, + "position1": 32579 + } + }, + { + "id": 55854, + "type": 44, + "batteryStatus": 3, + "batteryStrength": 187, + "roomId": 59611, + "firmware": { + "revision": 1, + "subRevision": 8, + "build": 1944 + }, + "motor": { + "revision": 51, + "subRevision": 51, + "build": 11825 + }, + "name": "U2hhZGUgMw==", + "groupId": 64003, + "aid": 3, + "signalStrength": 4, + "capabilities": 0, + "positions": { + "posKind1": 1, + "position1": 65534 + }, + "batteryKind": "unassigned" + }, + { + "id": 50150, + "type": 44, + "batteryStatus": 3, + "batteryStrength": 181, + "roomId": 59611, + "name": "U2hhZGUgMQ==", + "firmware": { + "revision": 1, + "subRevision": 8, + "build": 1944 + }, + "motor": { + "revision": 51, + "subRevision": 51, + "build": 11825 + }, + "groupId": 64003, + "aid": 4, + "signalStrength": 4, + "capabilities": 0, + "batteryKind": "unassigned", + "positions": { + "posKind1": 1, + "position1": 1040 + } + } + ] +} diff --git a/bundles/org.openhab.binding.hdpowerview/src/test/resources/org/openhab/binding/hdpowerview/sceneCollections.json b/bundles/org.openhab.binding.hdpowerview/src/test/resources/org/openhab/binding/hdpowerview/sceneCollections.json deleted file mode 100644 index 7631f89077..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/test/resources/org/openhab/binding/hdpowerview/sceneCollections.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "sceneCollectionIds": [ - 27119 - ], - "sceneCollectionData": [ - { - "name": "QsO4cm4gb3A=", - "colorId": 12, - "iconId": 17, - "id": 27119, - "order": 0, - "hkAssist": false - } - ] -} diff --git a/bundles/org.openhab.binding.hdpowerview/src/test/resources/org/openhab/binding/hdpowerview/scenes.json b/bundles/org.openhab.binding.hdpowerview/src/test/resources/org/openhab/binding/hdpowerview/scenes.json deleted file mode 100644 index 4cbe0a4339..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/test/resources/org/openhab/binding/hdpowerview/scenes.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "sceneIds": [ - 18097, - 22663, - 35821, - 6551 - ], - "sceneData": [ - { - "roomId": 59611, - "name": "RG9vciBPcGVu", - "colorId": 6, - "iconId": 160, - "networkNumber": 19, - "id": 18097, - "order": 3, - "hkAssist": false - }, - { - "roomId": 59611, - "name": "SGVhcnQ=", - "colorId": 15, - "iconId": 49, - "networkNumber": 3, - "id": 22663, - "order": 0, - "hkAssist": false - }, - { - "roomId": 59611, - "name": "Q2xvc2U=", - "colorId": 5, - "iconId": 31, - "networkNumber": 8, - "id": 35821, - "order": 2, - "hkAssist": false - }, - { - "roomId": 59611, - "name": "T3Blbg==", - "colorId": 10, - "iconId": 95, - "networkNumber": 20, - "id": 6551, - "order": 1, - "hkAssist": false - } - ] -} diff --git a/bundles/org.openhab.binding.hdpowerview/src/test/resources/org/openhab/binding/hdpowerview/shades.json b/bundles/org.openhab.binding.hdpowerview/src/test/resources/org/openhab/binding/hdpowerview/shades.json deleted file mode 100644 index cfbf435087..0000000000 --- a/bundles/org.openhab.binding.hdpowerview/src/test/resources/org/openhab/binding/hdpowerview/shades.json +++ /dev/null @@ -1,90 +0,0 @@ -{ - "shadeIds": [ - 25206, - 55854, - 50150 - ], - "shadeData": [ - { - "id": 25206, - "type": 44, - "batteryStatus": 3, - "batteryStrength": 179, - "roomId": 59611, - "firmware": { - "revision": 1, - "subRevision": 8, - "build": 1944 - }, - "name": "U2hhZGUgMg==", - "motor": { - "revision": 51, - "subRevision": 51, - "build": 11825 - }, - "groupId": 64003, - "aid": 2, - "signalStrength": 4, - "capabilities": 0, - "batteryKind": 1, - "positions": { - "posKind1": 3, - "position1": 32579 - } - }, - { - "id": 55854, - "type": 44, - "batteryStatus": 3, - "batteryStrength": 187, - "roomId": 59611, - "firmware": { - "revision": 1, - "subRevision": 8, - "build": 1944 - }, - "motor": { - "revision": 51, - "subRevision": 51, - "build": 11825 - }, - "name": "U2hhZGUgMw==", - "groupId": 64003, - "aid": 3, - "signalStrength": 4, - "capabilities": 0, - "positions": { - "posKind1": 1, - "position1": 65534 - }, - "batteryKind": "unassigned" - }, - { - "id": 50150, - "type": 44, - "batteryStatus": 3, - "batteryStrength": 181, - "roomId": 59611, - "name": "U2hhZGUgMQ==", - "firmware": { - "revision": 1, - "subRevision": 8, - "build": 1944 - }, - "motor": { - "revision": 51, - "subRevision": 51, - "build": 11825 - }, - "groupId": 64003, - "aid": 4, - "signalStrength": 4, - "capabilities": 0, - "batteryKind": "unassigned", - "positions": { - "posKind1": 1, - "position1": 1040 - } - } - ] -}