From 3389210fa18420d5d75c821fb5a1548ed6748250 Mon Sep 17 00:00:00 2001 From: udaw Date: Sun, 18 Oct 2026 23:31:33 +0200 Subject: [PATCH 1/2] Add custom min/max constructors to remaining range characteristics (#162) Add DEFAULT_MIN_VALUE/DEFAULT_MAX_VALUE (and DEFAULT_STEP for float characteristics) and a constructor taking min/max (and step) to 19 characteristics that only supported fixed ranges, following the pattern of RotationSpeedCharacteristic. Existing constructors delegate with the previous values, so their serialized output is unchanged. --- CHANGES.md | 3 + .../impl/audio/VolumeCharacteristic.java | 16 +- .../battery/BatteryLevelCharacteristic.java | 15 +- .../impl/common/WaterLavelCharacteristic.java | 19 +- .../FilterLifeLevelCharacteristic.java | 19 +- ...tyDehumidifierThresholdCharacteristic.java | 27 +- ...dityHumidifierThresholdCharacteristic.java | 27 +- ...CurrentRelativeHumidityCharacteristic.java | 19 +- .../TargetRelativeHumidityCharacteristic.java | 27 +- .../lightbulb/BrightnessCharacteristic.java | 16 +- .../impl/lightbulb/HueCharacteristic.java | 28 +- .../lightbulb/SaturationCharacteristic.java | 27 +- .../slat/CurrentTiltAngleCharacteristic.java | 15 +- .../slat/TargetTiltAngleCharacteristic.java | 16 +- ...rentHorizontalTiltAngleCharacteristic.java | 15 +- .../CurrentPositionCharacteristic.java | 15 +- ...urrentVerticalTiltAngleCharacteristic.java | 15 +- ...rgetHorizontalTiltAngleCharacteristic.java | 16 +- .../TargetPositionCharacteristic.java | 16 +- ...TargetVerticalTiltAngleCharacteristic.java | 16 +- .../impl/CustomRangeCharacteristicsTest.java | 253 ++++++++++++++++++ 21 files changed, 574 insertions(+), 46 deletions(-) create mode 100644 src/test/java/io/github/hapjava/characteristics/impl/CustomRangeCharacteristicsTest.java diff --git a/CHANGES.md b/CHANGES.md index a50fc7fae..6dfc34b6d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,6 @@ +# HAP-Java 2.0.10 +* Add constructors with custom min/max (and step for float values) to the remaining range characteristics [#162](https://github.com/hap-java/HAP-Java/issues/162) + # HAP-Java 2.0.9 * Fix Set Duration and Remaining Duration characteristics to advertise format `uint32` instead of `int` [#202](https://github.com/hap-java/HAP-Java/issues/202) * Stop logging the SRP shared secret, derived key and M5 message data during pairing at DEBUG level diff --git a/src/main/java/io/github/hapjava/characteristics/impl/audio/VolumeCharacteristic.java b/src/main/java/io/github/hapjava/characteristics/impl/audio/VolumeCharacteristic.java index 2d1caedd7..2a4223d5c 100644 --- a/src/main/java/io/github/hapjava/characteristics/impl/audio/VolumeCharacteristic.java +++ b/src/main/java/io/github/hapjava/characteristics/impl/audio/VolumeCharacteristic.java @@ -11,8 +11,12 @@ /** Volume characteristic to control audio volume. */ public class VolumeCharacteristic extends IntegerCharacteristic implements EventableCharacteristic { + public static final int DEFAULT_MIN_VALUE = 0; + public static final int DEFAULT_MAX_VALUE = 100; public VolumeCharacteristic( + int minValue, + int maxValue, Supplier> getter, ExceptionalConsumer setter, Consumer subscriber, @@ -20,12 +24,20 @@ public VolumeCharacteristic( super( "00000119-0000-1000-8000-0026BB765291", "volume", - 0, - 100, + minValue, + maxValue, "percentage", Optional.of(getter), Optional.of(setter), Optional.of(subscriber), Optional.of(unsubscriber)); } + + public VolumeCharacteristic( + Supplier> getter, + ExceptionalConsumer setter, + Consumer subscriber, + Runnable unsubscriber) { + this(DEFAULT_MIN_VALUE, DEFAULT_MAX_VALUE, getter, setter, subscriber, unsubscriber); + } } diff --git a/src/main/java/io/github/hapjava/characteristics/impl/battery/BatteryLevelCharacteristic.java b/src/main/java/io/github/hapjava/characteristics/impl/battery/BatteryLevelCharacteristic.java index 0fa56ff40..ae7097ccd 100644 --- a/src/main/java/io/github/hapjava/characteristics/impl/battery/BatteryLevelCharacteristic.java +++ b/src/main/java/io/github/hapjava/characteristics/impl/battery/BatteryLevelCharacteristic.java @@ -11,20 +11,31 @@ /** This characteristic describes the current level of the battery. */ public class BatteryLevelCharacteristic extends IntegerCharacteristic implements EventableCharacteristic { + public static final int DEFAULT_MIN_VALUE = 0; + public static final int DEFAULT_MAX_VALUE = 100; public BatteryLevelCharacteristic( + int minValue, + int maxValue, Supplier> getter, Consumer subscriber, Runnable unsubscriber) { super( "00000068-0000-1000-8000-0026BB765291", "battery level", - 0, - 100, + minValue, + maxValue, "%", Optional.of(getter), Optional.empty(), Optional.of(subscriber), Optional.of(unsubscriber)); } + + public BatteryLevelCharacteristic( + Supplier> getter, + Consumer subscriber, + Runnable unsubscriber) { + this(DEFAULT_MIN_VALUE, DEFAULT_MAX_VALUE, getter, subscriber, unsubscriber); + } } diff --git a/src/main/java/io/github/hapjava/characteristics/impl/common/WaterLavelCharacteristic.java b/src/main/java/io/github/hapjava/characteristics/impl/common/WaterLavelCharacteristic.java index dda11b087..d9d29bac7 100644 --- a/src/main/java/io/github/hapjava/characteristics/impl/common/WaterLavelCharacteristic.java +++ b/src/main/java/io/github/hapjava/characteristics/impl/common/WaterLavelCharacteristic.java @@ -11,21 +11,34 @@ /** This characteristic describes the water level. */ public class WaterLavelCharacteristic extends FloatCharacteristic implements EventableCharacteristic { + public static final double DEFAULT_MIN_VALUE = 0; + public static final double DEFAULT_MAX_VALUE = 100; + public static final double DEFAULT_STEP = 1; public WaterLavelCharacteristic( + double minValue, + double maxValue, + double minStep, Supplier> getter, Consumer subscriber, Runnable unsubscriber) { super( "000000B5-0000-1000-8000-0026BB765291", "water level", - 0, - 100, - 1, + minValue, + maxValue, + minStep, "%", Optional.of(getter), Optional.empty(), Optional.of(subscriber), Optional.of(unsubscriber)); } + + public WaterLavelCharacteristic( + Supplier> getter, + Consumer subscriber, + Runnable unsubscriber) { + this(DEFAULT_MIN_VALUE, DEFAULT_MAX_VALUE, DEFAULT_STEP, getter, subscriber, unsubscriber); + } } diff --git a/src/main/java/io/github/hapjava/characteristics/impl/filtermaintenance/FilterLifeLevelCharacteristic.java b/src/main/java/io/github/hapjava/characteristics/impl/filtermaintenance/FilterLifeLevelCharacteristic.java index 29cdf8d6e..6213769c9 100644 --- a/src/main/java/io/github/hapjava/characteristics/impl/filtermaintenance/FilterLifeLevelCharacteristic.java +++ b/src/main/java/io/github/hapjava/characteristics/impl/filtermaintenance/FilterLifeLevelCharacteristic.java @@ -10,21 +10,34 @@ public class FilterLifeLevelCharacteristic extends FloatCharacteristic implements EventableCharacteristic { + public static final double DEFAULT_MIN_VALUE = 0; + public static final double DEFAULT_MAX_VALUE = 100; + public static final double DEFAULT_STEP = 1; public FilterLifeLevelCharacteristic( + double minValue, + double maxValue, + double minStep, Supplier> getter, Consumer subscriber, Runnable unsubscriber) { super( "000000AB-0000-1000-8000-0026BB765291", "Filter Life Level", - 0, - 100, - 1, + minValue, + maxValue, + minStep, "%", Optional.of(getter), Optional.empty(), Optional.of(subscriber), Optional.of(unsubscriber)); } + + public FilterLifeLevelCharacteristic( + Supplier> getter, + Consumer subscriber, + Runnable unsubscriber) { + this(DEFAULT_MIN_VALUE, DEFAULT_MAX_VALUE, DEFAULT_STEP, getter, subscriber, unsubscriber); + } } diff --git a/src/main/java/io/github/hapjava/characteristics/impl/humidifier/HumidityDehumidifierThresholdCharacteristic.java b/src/main/java/io/github/hapjava/characteristics/impl/humidifier/HumidityDehumidifierThresholdCharacteristic.java index b8a4ca569..84a31fe24 100644 --- a/src/main/java/io/github/hapjava/characteristics/impl/humidifier/HumidityDehumidifierThresholdCharacteristic.java +++ b/src/main/java/io/github/hapjava/characteristics/impl/humidifier/HumidityDehumidifierThresholdCharacteristic.java @@ -13,8 +13,14 @@ * turns on. */ public class HumidityDehumidifierThresholdCharacteristic extends FloatCharacteristic { + public static final double DEFAULT_MIN_VALUE = 0; + public static final double DEFAULT_MAX_VALUE = 100; + public static final double DEFAULT_STEP = 1; public HumidityDehumidifierThresholdCharacteristic( + double minValue, + double maxValue, + double minStep, Supplier> getter, ExceptionalConsumer setter, Consumer subscriber, @@ -22,13 +28,28 @@ public HumidityDehumidifierThresholdCharacteristic( super( "000000C9-0000-1000-8000-0026BB765291", "humidity threshold dehumidifier", - 0, - 100, - 1, + minValue, + maxValue, + minStep, "%", Optional.of(getter), Optional.of(setter), Optional.of(subscriber), Optional.of(unsubscriber)); } + + public HumidityDehumidifierThresholdCharacteristic( + Supplier> getter, + ExceptionalConsumer setter, + Consumer subscriber, + Runnable unsubscriber) { + this( + DEFAULT_MIN_VALUE, + DEFAULT_MAX_VALUE, + DEFAULT_STEP, + getter, + setter, + subscriber, + unsubscriber); + } } diff --git a/src/main/java/io/github/hapjava/characteristics/impl/humidifier/HumidityHumidifierThresholdCharacteristic.java b/src/main/java/io/github/hapjava/characteristics/impl/humidifier/HumidityHumidifierThresholdCharacteristic.java index 2ee8adbf2..14b78bde1 100644 --- a/src/main/java/io/github/hapjava/characteristics/impl/humidifier/HumidityHumidifierThresholdCharacteristic.java +++ b/src/main/java/io/github/hapjava/characteristics/impl/humidifier/HumidityHumidifierThresholdCharacteristic.java @@ -13,8 +13,14 @@ * turns on. */ public class HumidityHumidifierThresholdCharacteristic extends FloatCharacteristic { + public static final double DEFAULT_MIN_VALUE = 0; + public static final double DEFAULT_MAX_VALUE = 100; + public static final double DEFAULT_STEP = 1; public HumidityHumidifierThresholdCharacteristic( + double minValue, + double maxValue, + double minStep, Supplier> getter, ExceptionalConsumer setter, Consumer subscriber, @@ -22,13 +28,28 @@ public HumidityHumidifierThresholdCharacteristic( super( "000000CA-0000-1000-8000-0026BB765291", "humidity threshold humidifier", - 0, - 100, - 1, + minValue, + maxValue, + minStep, "%", Optional.of(getter), Optional.of(setter), Optional.of(subscriber), Optional.of(unsubscriber)); } + + public HumidityHumidifierThresholdCharacteristic( + Supplier> getter, + ExceptionalConsumer setter, + Consumer subscriber, + Runnable unsubscriber) { + this( + DEFAULT_MIN_VALUE, + DEFAULT_MAX_VALUE, + DEFAULT_STEP, + getter, + setter, + subscriber, + unsubscriber); + } } diff --git a/src/main/java/io/github/hapjava/characteristics/impl/humiditysensor/CurrentRelativeHumidityCharacteristic.java b/src/main/java/io/github/hapjava/characteristics/impl/humiditysensor/CurrentRelativeHumidityCharacteristic.java index be77125b6..7ce18fb46 100644 --- a/src/main/java/io/github/hapjava/characteristics/impl/humiditysensor/CurrentRelativeHumidityCharacteristic.java +++ b/src/main/java/io/github/hapjava/characteristics/impl/humiditysensor/CurrentRelativeHumidityCharacteristic.java @@ -9,21 +9,34 @@ /** This characteristic describes the current relative humidity. */ public class CurrentRelativeHumidityCharacteristic extends FloatCharacteristic { + public static final double DEFAULT_MIN_VALUE = 0; + public static final double DEFAULT_MAX_VALUE = 100; + public static final double DEFAULT_STEP = 1; public CurrentRelativeHumidityCharacteristic( + double minValue, + double maxValue, + double minStep, Supplier> getter, Consumer subscriber, Runnable unsubscriber) { super( "00000010-0000-1000-8000-0026BB765291", "Current Relative Humidity", - 0, - 100, - 1, + minValue, + maxValue, + minStep, "%", Optional.of(getter), Optional.empty(), Optional.of(subscriber), Optional.of(unsubscriber)); } + + public CurrentRelativeHumidityCharacteristic( + Supplier> getter, + Consumer subscriber, + Runnable unsubscriber) { + this(DEFAULT_MIN_VALUE, DEFAULT_MAX_VALUE, DEFAULT_STEP, getter, subscriber, unsubscriber); + } } diff --git a/src/main/java/io/github/hapjava/characteristics/impl/humiditysensor/TargetRelativeHumidityCharacteristic.java b/src/main/java/io/github/hapjava/characteristics/impl/humiditysensor/TargetRelativeHumidityCharacteristic.java index ab8ad7e29..600ca0f7c 100644 --- a/src/main/java/io/github/hapjava/characteristics/impl/humiditysensor/TargetRelativeHumidityCharacteristic.java +++ b/src/main/java/io/github/hapjava/characteristics/impl/humiditysensor/TargetRelativeHumidityCharacteristic.java @@ -10,8 +10,14 @@ /** This characteristic describes the target relative humidity. */ public class TargetRelativeHumidityCharacteristic extends FloatCharacteristic { + public static final double DEFAULT_MIN_VALUE = 0; + public static final double DEFAULT_MAX_VALUE = 100; + public static final double DEFAULT_STEP = 1; public TargetRelativeHumidityCharacteristic( + double minValue, + double maxValue, + double minStep, Supplier> getter, ExceptionalConsumer setter, Consumer subscriber, @@ -19,13 +25,28 @@ public TargetRelativeHumidityCharacteristic( super( "00000034-0000-1000-8000-0026BB765291", "Target Relative Humidity", - 0, - 100, - 1, + minValue, + maxValue, + minStep, "%", Optional.of(getter), Optional.of(setter), Optional.of(subscriber), Optional.of(unsubscriber)); } + + public TargetRelativeHumidityCharacteristic( + Supplier> getter, + ExceptionalConsumer setter, + Consumer subscriber, + Runnable unsubscriber) { + this( + DEFAULT_MIN_VALUE, + DEFAULT_MAX_VALUE, + DEFAULT_STEP, + getter, + setter, + subscriber, + unsubscriber); + } } diff --git a/src/main/java/io/github/hapjava/characteristics/impl/lightbulb/BrightnessCharacteristic.java b/src/main/java/io/github/hapjava/characteristics/impl/lightbulb/BrightnessCharacteristic.java index 693e42efc..b68cb914b 100644 --- a/src/main/java/io/github/hapjava/characteristics/impl/lightbulb/BrightnessCharacteristic.java +++ b/src/main/java/io/github/hapjava/characteristics/impl/lightbulb/BrightnessCharacteristic.java @@ -15,8 +15,12 @@ */ public class BrightnessCharacteristic extends IntegerCharacteristic implements EventableCharacteristic { + public static final int DEFAULT_MIN_VALUE = 0; + public static final int DEFAULT_MAX_VALUE = 100; public BrightnessCharacteristic( + int minValue, + int maxValue, Supplier> getter, ExceptionalConsumer setter, Consumer subscriber, @@ -24,12 +28,20 @@ public BrightnessCharacteristic( super( "00000008-0000-1000-8000-0026BB765291", "level of brightness", - 0, - 100, + minValue, + maxValue, "%", Optional.of(getter), Optional.of(setter), Optional.of(subscriber), Optional.of(unsubscriber)); } + + public BrightnessCharacteristic( + Supplier> getter, + ExceptionalConsumer setter, + Consumer subscriber, + Runnable unsubscriber) { + this(DEFAULT_MIN_VALUE, DEFAULT_MAX_VALUE, getter, setter, subscriber, unsubscriber); + } } diff --git a/src/main/java/io/github/hapjava/characteristics/impl/lightbulb/HueCharacteristic.java b/src/main/java/io/github/hapjava/characteristics/impl/lightbulb/HueCharacteristic.java index 7a00816bc..f41a92319 100644 --- a/src/main/java/io/github/hapjava/characteristics/impl/lightbulb/HueCharacteristic.java +++ b/src/main/java/io/github/hapjava/characteristics/impl/lightbulb/HueCharacteristic.java @@ -10,7 +10,14 @@ /** This characteristic describes hue or color. */ public class HueCharacteristic extends FloatCharacteristic { + public static final double DEFAULT_MIN_VALUE = 0; + public static final double DEFAULT_MAX_VALUE = 360; + public static final double DEFAULT_STEP = 1; + public HueCharacteristic( + double minValue, + double maxValue, + double minStep, Supplier> getter, ExceptionalConsumer setter, Consumer subscriber, @@ -18,13 +25,28 @@ public HueCharacteristic( super( "00000013-0000-1000-8000-0026BB765291", "hue or color", - 0, - 360, - 1, + minValue, + maxValue, + minStep, "arcdegrees", Optional.of(getter), Optional.of(setter), Optional.of(subscriber), Optional.of(unsubscriber)); } + + public HueCharacteristic( + Supplier> getter, + ExceptionalConsumer setter, + Consumer subscriber, + Runnable unsubscriber) { + this( + DEFAULT_MIN_VALUE, + DEFAULT_MAX_VALUE, + DEFAULT_STEP, + getter, + setter, + subscriber, + unsubscriber); + } } diff --git a/src/main/java/io/github/hapjava/characteristics/impl/lightbulb/SaturationCharacteristic.java b/src/main/java/io/github/hapjava/characteristics/impl/lightbulb/SaturationCharacteristic.java index 90694ef98..5d2f7033b 100644 --- a/src/main/java/io/github/hapjava/characteristics/impl/lightbulb/SaturationCharacteristic.java +++ b/src/main/java/io/github/hapjava/characteristics/impl/lightbulb/SaturationCharacteristic.java @@ -12,8 +12,14 @@ /** This characteristic describes color saturation. */ public class SaturationCharacteristic extends FloatCharacteristic implements EventableCharacteristic { + public static final double DEFAULT_MIN_VALUE = 0; + public static final double DEFAULT_MAX_VALUE = 100; + public static final double DEFAULT_STEP = 1; public SaturationCharacteristic( + double minValue, + double maxValue, + double minStep, Supplier> getter, ExceptionalConsumer setter, Consumer subscriber, @@ -21,13 +27,28 @@ public SaturationCharacteristic( super( "0000002F-0000-1000-8000-0026BB765291", "color saturation", - 0, - 100, - 1, + minValue, + maxValue, + minStep, "%", Optional.of(getter), Optional.of(setter), Optional.of(subscriber), Optional.of(unsubscriber)); } + + public SaturationCharacteristic( + Supplier> getter, + ExceptionalConsumer setter, + Consumer subscriber, + Runnable unsubscriber) { + this( + DEFAULT_MIN_VALUE, + DEFAULT_MAX_VALUE, + DEFAULT_STEP, + getter, + setter, + subscriber, + unsubscriber); + } } diff --git a/src/main/java/io/github/hapjava/characteristics/impl/slat/CurrentTiltAngleCharacteristic.java b/src/main/java/io/github/hapjava/characteristics/impl/slat/CurrentTiltAngleCharacteristic.java index 3a4868b2c..0f186281a 100644 --- a/src/main/java/io/github/hapjava/characteristics/impl/slat/CurrentTiltAngleCharacteristic.java +++ b/src/main/java/io/github/hapjava/characteristics/impl/slat/CurrentTiltAngleCharacteristic.java @@ -11,20 +11,31 @@ /** This characteristic describe current tilt angle (between -90 and 90) */ public class CurrentTiltAngleCharacteristic extends IntegerCharacteristic implements EventableCharacteristic { + public static final int DEFAULT_MIN_VALUE = -90; + public static final int DEFAULT_MAX_VALUE = 90; public CurrentTiltAngleCharacteristic( + int minValue, + int maxValue, Supplier> getter, Consumer subscriber, Runnable unsubscriber) { super( "000000C1-0000-1000-8000-0026BB765291", "current tilt angle", - -90, - 90, + minValue, + maxValue, "arcdegrees", Optional.of(getter), Optional.empty(), Optional.of(subscriber), Optional.of(unsubscriber)); } + + public CurrentTiltAngleCharacteristic( + Supplier> getter, + Consumer subscriber, + Runnable unsubscriber) { + this(DEFAULT_MIN_VALUE, DEFAULT_MAX_VALUE, getter, subscriber, unsubscriber); + } } diff --git a/src/main/java/io/github/hapjava/characteristics/impl/slat/TargetTiltAngleCharacteristic.java b/src/main/java/io/github/hapjava/characteristics/impl/slat/TargetTiltAngleCharacteristic.java index 2a327522d..44824f350 100644 --- a/src/main/java/io/github/hapjava/characteristics/impl/slat/TargetTiltAngleCharacteristic.java +++ b/src/main/java/io/github/hapjava/characteristics/impl/slat/TargetTiltAngleCharacteristic.java @@ -12,8 +12,12 @@ /** This characteristic describes the target angle of slats. */ public class TargetTiltAngleCharacteristic extends IntegerCharacteristic implements EventableCharacteristic { + public static final int DEFAULT_MIN_VALUE = -90; + public static final int DEFAULT_MAX_VALUE = 90; public TargetTiltAngleCharacteristic( + int minValue, + int maxValue, Supplier> getter, ExceptionalConsumer setter, Consumer subscriber, @@ -21,12 +25,20 @@ public TargetTiltAngleCharacteristic( super( "000000C2-0000-1000-8000-0026BB765291", "target tilt angle", - -90, - 90, + minValue, + maxValue, "arcdegrees", Optional.of(getter), Optional.of(setter), Optional.of(subscriber), Optional.of(unsubscriber)); } + + public TargetTiltAngleCharacteristic( + Supplier> getter, + ExceptionalConsumer setter, + Consumer subscriber, + Runnable unsubscriber) { + this(DEFAULT_MIN_VALUE, DEFAULT_MAX_VALUE, getter, setter, subscriber, unsubscriber); + } } diff --git a/src/main/java/io/github/hapjava/characteristics/impl/windowcovering/CurrentHorizontalTiltAngleCharacteristic.java b/src/main/java/io/github/hapjava/characteristics/impl/windowcovering/CurrentHorizontalTiltAngleCharacteristic.java index 1255d7eff..272a822f5 100644 --- a/src/main/java/io/github/hapjava/characteristics/impl/windowcovering/CurrentHorizontalTiltAngleCharacteristic.java +++ b/src/main/java/io/github/hapjava/characteristics/impl/windowcovering/CurrentHorizontalTiltAngleCharacteristic.java @@ -11,20 +11,31 @@ /** This characteristic describes the current angle of horizontal slats. */ public class CurrentHorizontalTiltAngleCharacteristic extends IntegerCharacteristic implements EventableCharacteristic { + public static final int DEFAULT_MIN_VALUE = -90; + public static final int DEFAULT_MAX_VALUE = 90; public CurrentHorizontalTiltAngleCharacteristic( + int minValue, + int maxValue, Supplier> getter, Consumer subscriber, Runnable unsubscriber) { super( "0000006C-0000-1000-8000-0026BB765291", "current horizontal tilt angle", - -90, - 90, + minValue, + maxValue, "arcdegrees", Optional.of(getter), Optional.empty(), Optional.of(subscriber), Optional.of(unsubscriber)); } + + public CurrentHorizontalTiltAngleCharacteristic( + Supplier> getter, + Consumer subscriber, + Runnable unsubscriber) { + this(DEFAULT_MIN_VALUE, DEFAULT_MAX_VALUE, getter, subscriber, unsubscriber); + } } diff --git a/src/main/java/io/github/hapjava/characteristics/impl/windowcovering/CurrentPositionCharacteristic.java b/src/main/java/io/github/hapjava/characteristics/impl/windowcovering/CurrentPositionCharacteristic.java index d51614615..e9ed063c8 100644 --- a/src/main/java/io/github/hapjava/characteristics/impl/windowcovering/CurrentPositionCharacteristic.java +++ b/src/main/java/io/github/hapjava/characteristics/impl/windowcovering/CurrentPositionCharacteristic.java @@ -11,20 +11,31 @@ /** This characteristic describes the current position of accessories. */ public class CurrentPositionCharacteristic extends IntegerCharacteristic implements EventableCharacteristic { + public static final int DEFAULT_MIN_VALUE = 0; + public static final int DEFAULT_MAX_VALUE = 100; public CurrentPositionCharacteristic( + int minValue, + int maxValue, Supplier> getter, Consumer subscriber, Runnable unsubscriber) { super( "0000006D-0000-1000-8000-0026BB765291", "current position", - 0, - 100, + minValue, + maxValue, "%", Optional.of(getter), Optional.empty(), Optional.of(subscriber), Optional.of(unsubscriber)); } + + public CurrentPositionCharacteristic( + Supplier> getter, + Consumer subscriber, + Runnable unsubscriber) { + this(DEFAULT_MIN_VALUE, DEFAULT_MAX_VALUE, getter, subscriber, unsubscriber); + } } diff --git a/src/main/java/io/github/hapjava/characteristics/impl/windowcovering/CurrentVerticalTiltAngleCharacteristic.java b/src/main/java/io/github/hapjava/characteristics/impl/windowcovering/CurrentVerticalTiltAngleCharacteristic.java index c6258a2db..7d7168973 100644 --- a/src/main/java/io/github/hapjava/characteristics/impl/windowcovering/CurrentVerticalTiltAngleCharacteristic.java +++ b/src/main/java/io/github/hapjava/characteristics/impl/windowcovering/CurrentVerticalTiltAngleCharacteristic.java @@ -11,20 +11,31 @@ /** This characteristic describes the current angle of vertical slats for accessory. */ public class CurrentVerticalTiltAngleCharacteristic extends IntegerCharacteristic implements EventableCharacteristic { + public static final int DEFAULT_MIN_VALUE = -90; + public static final int DEFAULT_MAX_VALUE = 90; public CurrentVerticalTiltAngleCharacteristic( + int minValue, + int maxValue, Supplier> getter, Consumer subscriber, Runnable unsubscriber) { super( "0000006E-0000-1000-8000-0026BB765291", "current vertical tilt angle", - -90, - 90, + minValue, + maxValue, "arcdegrees", Optional.of(getter), Optional.empty(), Optional.of(subscriber), Optional.of(unsubscriber)); } + + public CurrentVerticalTiltAngleCharacteristic( + Supplier> getter, + Consumer subscriber, + Runnable unsubscriber) { + this(DEFAULT_MIN_VALUE, DEFAULT_MAX_VALUE, getter, subscriber, unsubscriber); + } } diff --git a/src/main/java/io/github/hapjava/characteristics/impl/windowcovering/TargetHorizontalTiltAngleCharacteristic.java b/src/main/java/io/github/hapjava/characteristics/impl/windowcovering/TargetHorizontalTiltAngleCharacteristic.java index 38c075760..17639ba6e 100644 --- a/src/main/java/io/github/hapjava/characteristics/impl/windowcovering/TargetHorizontalTiltAngleCharacteristic.java +++ b/src/main/java/io/github/hapjava/characteristics/impl/windowcovering/TargetHorizontalTiltAngleCharacteristic.java @@ -12,8 +12,12 @@ /** This characteristic describes the target angle of horizontal slats for accessories. */ public class TargetHorizontalTiltAngleCharacteristic extends IntegerCharacteristic implements EventableCharacteristic { + public static final int DEFAULT_MIN_VALUE = -90; + public static final int DEFAULT_MAX_VALUE = 90; public TargetHorizontalTiltAngleCharacteristic( + int minValue, + int maxValue, Supplier> getter, ExceptionalConsumer setter, Consumer subscriber, @@ -21,12 +25,20 @@ public TargetHorizontalTiltAngleCharacteristic( super( "0000007B-0000-1000-8000-0026BB765291", "target horizontal tilt angle", - -90, - 90, + minValue, + maxValue, "arcdegrees", Optional.of(getter), Optional.of(setter), Optional.of(subscriber), Optional.of(unsubscriber)); } + + public TargetHorizontalTiltAngleCharacteristic( + Supplier> getter, + ExceptionalConsumer setter, + Consumer subscriber, + Runnable unsubscriber) { + this(DEFAULT_MIN_VALUE, DEFAULT_MAX_VALUE, getter, setter, subscriber, unsubscriber); + } } diff --git a/src/main/java/io/github/hapjava/characteristics/impl/windowcovering/TargetPositionCharacteristic.java b/src/main/java/io/github/hapjava/characteristics/impl/windowcovering/TargetPositionCharacteristic.java index 6398a0b37..82d06c4b2 100644 --- a/src/main/java/io/github/hapjava/characteristics/impl/windowcovering/TargetPositionCharacteristic.java +++ b/src/main/java/io/github/hapjava/characteristics/impl/windowcovering/TargetPositionCharacteristic.java @@ -12,8 +12,12 @@ /** This characteristic describes the target position of accessories like door, window, blinds. */ public class TargetPositionCharacteristic extends IntegerCharacteristic implements EventableCharacteristic { + public static final int DEFAULT_MIN_VALUE = 0; + public static final int DEFAULT_MAX_VALUE = 100; public TargetPositionCharacteristic( + int minValue, + int maxValue, Supplier> getter, ExceptionalConsumer setter, Consumer subscriber, @@ -21,12 +25,20 @@ public TargetPositionCharacteristic( super( "0000007C-0000-1000-8000-0026BB765291", "target position", - 0, - 100, + minValue, + maxValue, "%", Optional.of(getter), Optional.of(setter), Optional.of(subscriber), Optional.of(unsubscriber)); } + + public TargetPositionCharacteristic( + Supplier> getter, + ExceptionalConsumer setter, + Consumer subscriber, + Runnable unsubscriber) { + this(DEFAULT_MIN_VALUE, DEFAULT_MAX_VALUE, getter, setter, subscriber, unsubscriber); + } } diff --git a/src/main/java/io/github/hapjava/characteristics/impl/windowcovering/TargetVerticalTiltAngleCharacteristic.java b/src/main/java/io/github/hapjava/characteristics/impl/windowcovering/TargetVerticalTiltAngleCharacteristic.java index 4d7c3ad71..03fd7a3f5 100644 --- a/src/main/java/io/github/hapjava/characteristics/impl/windowcovering/TargetVerticalTiltAngleCharacteristic.java +++ b/src/main/java/io/github/hapjava/characteristics/impl/windowcovering/TargetVerticalTiltAngleCharacteristic.java @@ -12,8 +12,12 @@ /** This characteristic describes the target angle of vertical slats. */ public class TargetVerticalTiltAngleCharacteristic extends IntegerCharacteristic implements EventableCharacteristic { + public static final int DEFAULT_MIN_VALUE = -90; + public static final int DEFAULT_MAX_VALUE = 90; public TargetVerticalTiltAngleCharacteristic( + int minValue, + int maxValue, Supplier> getter, ExceptionalConsumer setter, Consumer subscriber, @@ -21,12 +25,20 @@ public TargetVerticalTiltAngleCharacteristic( super( "0000007D-0000-1000-8000-0026BB765291", "target vertical tilt angle", - -90, - 90, + minValue, + maxValue, "arcdegrees", Optional.of(getter), Optional.of(setter), Optional.of(subscriber), Optional.of(unsubscriber)); } + + public TargetVerticalTiltAngleCharacteristic( + Supplier> getter, + ExceptionalConsumer setter, + Consumer subscriber, + Runnable unsubscriber) { + this(DEFAULT_MIN_VALUE, DEFAULT_MAX_VALUE, getter, setter, subscriber, unsubscriber); + } } diff --git a/src/test/java/io/github/hapjava/characteristics/impl/CustomRangeCharacteristicsTest.java b/src/test/java/io/github/hapjava/characteristics/impl/CustomRangeCharacteristicsTest.java new file mode 100644 index 000000000..800719d6d --- /dev/null +++ b/src/test/java/io/github/hapjava/characteristics/impl/CustomRangeCharacteristicsTest.java @@ -0,0 +1,253 @@ +package io.github.hapjava.characteristics.impl; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.github.hapjava.characteristics.Characteristic; +import io.github.hapjava.characteristics.impl.audio.VolumeCharacteristic; +import io.github.hapjava.characteristics.impl.battery.BatteryLevelCharacteristic; +import io.github.hapjava.characteristics.impl.common.WaterLavelCharacteristic; +import io.github.hapjava.characteristics.impl.filtermaintenance.FilterLifeLevelCharacteristic; +import io.github.hapjava.characteristics.impl.humidifier.HumidityDehumidifierThresholdCharacteristic; +import io.github.hapjava.characteristics.impl.humidifier.HumidityHumidifierThresholdCharacteristic; +import io.github.hapjava.characteristics.impl.humiditysensor.CurrentRelativeHumidityCharacteristic; +import io.github.hapjava.characteristics.impl.humiditysensor.TargetRelativeHumidityCharacteristic; +import io.github.hapjava.characteristics.impl.lightbulb.BrightnessCharacteristic; +import io.github.hapjava.characteristics.impl.lightbulb.HueCharacteristic; +import io.github.hapjava.characteristics.impl.lightbulb.SaturationCharacteristic; +import io.github.hapjava.characteristics.impl.slat.CurrentTiltAngleCharacteristic; +import io.github.hapjava.characteristics.impl.slat.TargetTiltAngleCharacteristic; +import io.github.hapjava.characteristics.impl.windowcovering.CurrentHorizontalTiltAngleCharacteristic; +import io.github.hapjava.characteristics.impl.windowcovering.CurrentPositionCharacteristic; +import io.github.hapjava.characteristics.impl.windowcovering.CurrentVerticalTiltAngleCharacteristic; +import io.github.hapjava.characteristics.impl.windowcovering.TargetHorizontalTiltAngleCharacteristic; +import io.github.hapjava.characteristics.impl.windowcovering.TargetPositionCharacteristic; +import io.github.hapjava.characteristics.impl.windowcovering.TargetVerticalTiltAngleCharacteristic; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import javax.json.JsonObject; +import org.junit.Test; + +/** Custom min/max support, see https://github.com/hap-java/HAP-Java/issues/162 */ +public class CustomRangeCharacteristicsTest { + + /** Serialized output of the default constructors, captured before custom ranges were added. */ + private static final List DEFAULT_CONSTRUCTORS = + Arrays.asList( + Case.of( + "BatteryLevelCharacteristic", + new BatteryLevelCharacteristic( + () -> CompletableFuture.completedFuture(50), cb -> {}, () -> {}), + "{\"iid\":7,\"type\":\"68\",\"perms\":[\"pr\",\"ev\"],\"format\":\"int\",\"value\":50,\"minValue\":0,\"maxValue\":100,\"minStep\":1,\"unit\":\"%\"}"), + Case.of( + "BrightnessCharacteristic", + new BrightnessCharacteristic( + () -> CompletableFuture.completedFuture(50), v -> {}, cb -> {}, () -> {}), + "{\"iid\":7,\"type\":\"8\",\"perms\":[\"pr\",\"pw\",\"ev\"],\"format\":\"int\",\"value\":50,\"minValue\":0,\"maxValue\":100,\"minStep\":1,\"unit\":\"%\"}"), + Case.of( + "CurrentPositionCharacteristic", + new CurrentPositionCharacteristic( + () -> CompletableFuture.completedFuture(50), cb -> {}, () -> {}), + "{\"iid\":7,\"type\":\"6D\",\"perms\":[\"pr\",\"ev\"],\"format\":\"int\",\"value\":50,\"minValue\":0,\"maxValue\":100,\"minStep\":1,\"unit\":\"%\"}"), + Case.of( + "TargetPositionCharacteristic", + new TargetPositionCharacteristic( + () -> CompletableFuture.completedFuture(50), v -> {}, cb -> {}, () -> {}), + "{\"iid\":7,\"type\":\"7C\",\"perms\":[\"pr\",\"pw\",\"ev\"],\"format\":\"int\",\"value\":50,\"minValue\":0,\"maxValue\":100,\"minStep\":1,\"unit\":\"%\"}"), + Case.of( + "VolumeCharacteristic", + new VolumeCharacteristic( + () -> CompletableFuture.completedFuture(50), v -> {}, cb -> {}, () -> {}), + "{\"iid\":7,\"type\":\"119\",\"perms\":[\"pr\",\"pw\",\"ev\"],\"format\":\"int\",\"value\":50,\"minValue\":0,\"maxValue\":100,\"minStep\":1,\"unit\":\"percentage\"}"), + Case.of( + "CurrentTiltAngleCharacteristic", + new CurrentTiltAngleCharacteristic( + () -> CompletableFuture.completedFuture(50), cb -> {}, () -> {}), + "{\"iid\":7,\"type\":\"C1\",\"perms\":[\"pr\",\"ev\"],\"format\":\"int\",\"value\":50,\"minValue\":-90,\"maxValue\":90,\"minStep\":1,\"unit\":\"arcdegrees\"}"), + Case.of( + "TargetTiltAngleCharacteristic", + new TargetTiltAngleCharacteristic( + () -> CompletableFuture.completedFuture(50), v -> {}, cb -> {}, () -> {}), + "{\"iid\":7,\"type\":\"C2\",\"perms\":[\"pr\",\"pw\",\"ev\"],\"format\":\"int\",\"value\":50,\"minValue\":-90,\"maxValue\":90,\"minStep\":1,\"unit\":\"arcdegrees\"}"), + Case.of( + "CurrentHorizontalTiltAngleCharacteristic", + new CurrentHorizontalTiltAngleCharacteristic( + () -> CompletableFuture.completedFuture(50), cb -> {}, () -> {}), + "{\"iid\":7,\"type\":\"6C\",\"perms\":[\"pr\",\"ev\"],\"format\":\"int\",\"value\":50,\"minValue\":-90,\"maxValue\":90,\"minStep\":1,\"unit\":\"arcdegrees\"}"), + Case.of( + "TargetHorizontalTiltAngleCharacteristic", + new TargetHorizontalTiltAngleCharacteristic( + () -> CompletableFuture.completedFuture(50), v -> {}, cb -> {}, () -> {}), + "{\"iid\":7,\"type\":\"7B\",\"perms\":[\"pr\",\"pw\",\"ev\"],\"format\":\"int\",\"value\":50,\"minValue\":-90,\"maxValue\":90,\"minStep\":1,\"unit\":\"arcdegrees\"}"), + Case.of( + "CurrentVerticalTiltAngleCharacteristic", + new CurrentVerticalTiltAngleCharacteristic( + () -> CompletableFuture.completedFuture(50), cb -> {}, () -> {}), + "{\"iid\":7,\"type\":\"6E\",\"perms\":[\"pr\",\"ev\"],\"format\":\"int\",\"value\":50,\"minValue\":-90,\"maxValue\":90,\"minStep\":1,\"unit\":\"arcdegrees\"}"), + Case.of( + "TargetVerticalTiltAngleCharacteristic", + new TargetVerticalTiltAngleCharacteristic( + () -> CompletableFuture.completedFuture(50), v -> {}, cb -> {}, () -> {}), + "{\"iid\":7,\"type\":\"7D\",\"perms\":[\"pr\",\"pw\",\"ev\"],\"format\":\"int\",\"value\":50,\"minValue\":-90,\"maxValue\":90,\"minStep\":1,\"unit\":\"arcdegrees\"}"), + Case.of( + "CurrentRelativeHumidityCharacteristic", + new CurrentRelativeHumidityCharacteristic( + () -> CompletableFuture.completedFuture(50.0), cb -> {}, () -> {}), + "{\"iid\":7,\"type\":\"10\",\"perms\":[\"pr\",\"ev\"],\"format\":\"float\",\"value\":50.0,\"minValue\":0.0,\"maxValue\":100.0,\"minStep\":1.0,\"unit\":\"%\"}"), + Case.of( + "TargetRelativeHumidityCharacteristic", + new TargetRelativeHumidityCharacteristic( + () -> CompletableFuture.completedFuture(50.0), v -> {}, cb -> {}, () -> {}), + "{\"iid\":7,\"type\":\"34\",\"perms\":[\"pr\",\"pw\",\"ev\"],\"format\":\"float\",\"value\":50.0,\"minValue\":0.0,\"maxValue\":100.0,\"minStep\":1.0,\"unit\":\"%\"}"), + Case.of( + "FilterLifeLevelCharacteristic", + new FilterLifeLevelCharacteristic( + () -> CompletableFuture.completedFuture(50.0), cb -> {}, () -> {}), + "{\"iid\":7,\"type\":\"AB\",\"perms\":[\"pr\",\"ev\"],\"format\":\"float\",\"value\":50.0,\"minValue\":0.0,\"maxValue\":100.0,\"minStep\":1.0,\"unit\":\"%\"}"), + Case.of( + "HueCharacteristic", + new HueCharacteristic( + () -> CompletableFuture.completedFuture(50.0), v -> {}, cb -> {}, () -> {}), + "{\"iid\":7,\"type\":\"13\",\"perms\":[\"pr\",\"pw\",\"ev\"],\"format\":\"float\",\"value\":50.0,\"minValue\":0.0,\"maxValue\":360.0,\"minStep\":1.0,\"unit\":\"arcdegrees\"}"), + Case.of( + "SaturationCharacteristic", + new SaturationCharacteristic( + () -> CompletableFuture.completedFuture(50.0), v -> {}, cb -> {}, () -> {}), + "{\"iid\":7,\"type\":\"2F\",\"perms\":[\"pr\",\"pw\",\"ev\"],\"format\":\"float\",\"value\":50.0,\"minValue\":0.0,\"maxValue\":100.0,\"minStep\":1.0,\"unit\":\"%\"}"), + Case.of( + "HumidityDehumidifierThresholdCharacteristic", + new HumidityDehumidifierThresholdCharacteristic( + () -> CompletableFuture.completedFuture(50.0), v -> {}, cb -> {}, () -> {}), + "{\"iid\":7,\"type\":\"C9\",\"perms\":[\"pr\",\"pw\",\"ev\"],\"format\":\"float\",\"value\":50.0,\"minValue\":0.0,\"maxValue\":100.0,\"minStep\":1.0,\"unit\":\"%\"}"), + Case.of( + "HumidityHumidifierThresholdCharacteristic", + new HumidityHumidifierThresholdCharacteristic( + () -> CompletableFuture.completedFuture(50.0), v -> {}, cb -> {}, () -> {}), + "{\"iid\":7,\"type\":\"CA\",\"perms\":[\"pr\",\"pw\",\"ev\"],\"format\":\"float\",\"value\":50.0,\"minValue\":0.0,\"maxValue\":100.0,\"minStep\":1.0,\"unit\":\"%\"}"), + Case.of( + "WaterLavelCharacteristic", + new WaterLavelCharacteristic( + () -> CompletableFuture.completedFuture(50.0), cb -> {}, () -> {}), + "{\"iid\":7,\"type\":\"B5\",\"perms\":[\"pr\",\"ev\"],\"format\":\"float\",\"value\":50.0,\"minValue\":0.0,\"maxValue\":100.0,\"minStep\":1.0,\"unit\":\"%\"}")); + + @Test + public void defaultConstructorsKeepTheirSerializedOutput() { + for (Case c : DEFAULT_CONSTRUCTORS) { + assertThat(c.characteristic.toJson(7).join().toString()).as(c.name).isEqualTo(c.expectedJson); + } + } + + @Test + public void integerCharacteristicsAdvertiseCustomRange() { + for (Characteristic c : + Arrays.asList( + new BatteryLevelCharacteristic( + 10, 20, () -> CompletableFuture.completedFuture(50), cb -> {}, () -> {}), + new BrightnessCharacteristic( + 10, 20, () -> CompletableFuture.completedFuture(50), v -> {}, cb -> {}, () -> {}), + new CurrentPositionCharacteristic( + 10, 20, () -> CompletableFuture.completedFuture(50), cb -> {}, () -> {}), + new TargetPositionCharacteristic( + 10, 20, () -> CompletableFuture.completedFuture(50), v -> {}, cb -> {}, () -> {}), + new VolumeCharacteristic( + 10, 20, () -> CompletableFuture.completedFuture(50), v -> {}, cb -> {}, () -> {}), + new CurrentTiltAngleCharacteristic( + 10, 20, () -> CompletableFuture.completedFuture(50), cb -> {}, () -> {}), + new TargetTiltAngleCharacteristic( + 10, 20, () -> CompletableFuture.completedFuture(50), v -> {}, cb -> {}, () -> {}), + new CurrentHorizontalTiltAngleCharacteristic( + 10, 20, () -> CompletableFuture.completedFuture(50), cb -> {}, () -> {}), + new TargetHorizontalTiltAngleCharacteristic( + 10, 20, () -> CompletableFuture.completedFuture(50), v -> {}, cb -> {}, () -> {}), + new CurrentVerticalTiltAngleCharacteristic( + 10, 20, () -> CompletableFuture.completedFuture(50), cb -> {}, () -> {}), + new TargetVerticalTiltAngleCharacteristic( + 10, + 20, + () -> CompletableFuture.completedFuture(50), + v -> {}, + cb -> {}, + () -> {}))) { + JsonObject json = c.toJson(7).join(); + String name = c.getClass().getSimpleName(); + assertThat(json.getInt("minValue")).as(name).isEqualTo(10); + assertThat(json.getInt("maxValue")).as(name).isEqualTo(20); + assertThat(json.getInt("minStep")).as(name).isEqualTo(1); + } + } + + @Test + public void floatCharacteristicsAdvertiseCustomRangeAndClampToIt() { + for (Characteristic c : + Arrays.asList( + new CurrentRelativeHumidityCharacteristic( + 10, 20, 0.5, () -> CompletableFuture.completedFuture(50.0), cb -> {}, () -> {}), + new TargetRelativeHumidityCharacteristic( + 10, + 20, + 0.5, + () -> CompletableFuture.completedFuture(50.0), + v -> {}, + cb -> {}, + () -> {}), + new FilterLifeLevelCharacteristic( + 10, 20, 0.5, () -> CompletableFuture.completedFuture(50.0), cb -> {}, () -> {}), + new HueCharacteristic( + 10, + 20, + 0.5, + () -> CompletableFuture.completedFuture(50.0), + v -> {}, + cb -> {}, + () -> {}), + new SaturationCharacteristic( + 10, + 20, + 0.5, + () -> CompletableFuture.completedFuture(50.0), + v -> {}, + cb -> {}, + () -> {}), + new HumidityDehumidifierThresholdCharacteristic( + 10, + 20, + 0.5, + () -> CompletableFuture.completedFuture(50.0), + v -> {}, + cb -> {}, + () -> {}), + new HumidityHumidifierThresholdCharacteristic( + 10, + 20, + 0.5, + () -> CompletableFuture.completedFuture(50.0), + v -> {}, + cb -> {}, + () -> {}), + new WaterLavelCharacteristic( + 10, 20, 0.5, () -> CompletableFuture.completedFuture(50.0), cb -> {}, () -> {}))) { + JsonObject json = c.toJson(7).join(); + String name = c.getClass().getSimpleName(); + assertThat(json.getJsonNumber("minValue").doubleValue()).as(name).isEqualTo(10.0); + assertThat(json.getJsonNumber("maxValue").doubleValue()).as(name).isEqualTo(20.0); + assertThat(json.getJsonNumber("minStep").doubleValue()).as(name).isEqualTo(0.5); + assertThat(json.getJsonNumber("value").doubleValue()).as(name).isEqualTo(20.0); + } + } + + private static class Case { + final String name; + final Characteristic characteristic; + final String expectedJson; + + private Case(String name, Characteristic characteristic, String expectedJson) { + this.name = name; + this.characteristic = characteristic; + this.expectedJson = expectedJson; + } + + static Case of(String name, Characteristic characteristic, String expectedJson) { + return new Case(name, characteristic, expectedJson); + } + } +} From a2a6bffa2b9a636ddb7c0164d8801208a83410a1 Mon Sep 17 00:00:00 2001 From: udaw Date: Mon, 19 Oct 2026 17:03:53 +0200 Subject: [PATCH 2/2] Limit custom min/max to tilt angle characteristics Percentage characteristics and hue have fixed ranges by definition, so only the tilt angles keep the min/max constructors. --- CHANGES.md | 2 +- .../impl/audio/VolumeCharacteristic.java | 16 +- .../battery/BatteryLevelCharacteristic.java | 15 +- .../impl/common/WaterLavelCharacteristic.java | 19 +- .../FilterLifeLevelCharacteristic.java | 19 +- ...tyDehumidifierThresholdCharacteristic.java | 27 +- ...dityHumidifierThresholdCharacteristic.java | 27 +- ...CurrentRelativeHumidityCharacteristic.java | 19 +- .../TargetRelativeHumidityCharacteristic.java | 27 +- .../lightbulb/BrightnessCharacteristic.java | 16 +- .../impl/lightbulb/HueCharacteristic.java | 28 +- .../lightbulb/SaturationCharacteristic.java | 27 +- .../CurrentPositionCharacteristic.java | 15 +- .../TargetPositionCharacteristic.java | 16 +- .../impl/CustomRangeCharacteristicsTest.java | 253 ------------------ .../impl/CustomTiltAngleRangeTest.java | 92 +++++++ 16 files changed, 127 insertions(+), 491 deletions(-) delete mode 100644 src/test/java/io/github/hapjava/characteristics/impl/CustomRangeCharacteristicsTest.java create mode 100644 src/test/java/io/github/hapjava/characteristics/impl/CustomTiltAngleRangeTest.java diff --git a/CHANGES.md b/CHANGES.md index 6dfc34b6d..f6be4cdb6 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,5 @@ # HAP-Java 2.0.10 -* Add constructors with custom min/max (and step for float values) to the remaining range characteristics [#162](https://github.com/hap-java/HAP-Java/issues/162) +* Add constructors with custom min/max to the tilt angle characteristics [#162](https://github.com/hap-java/HAP-Java/issues/162) # HAP-Java 2.0.9 * Fix Set Duration and Remaining Duration characteristics to advertise format `uint32` instead of `int` [#202](https://github.com/hap-java/HAP-Java/issues/202) diff --git a/src/main/java/io/github/hapjava/characteristics/impl/audio/VolumeCharacteristic.java b/src/main/java/io/github/hapjava/characteristics/impl/audio/VolumeCharacteristic.java index 2a4223d5c..2d1caedd7 100644 --- a/src/main/java/io/github/hapjava/characteristics/impl/audio/VolumeCharacteristic.java +++ b/src/main/java/io/github/hapjava/characteristics/impl/audio/VolumeCharacteristic.java @@ -11,12 +11,8 @@ /** Volume characteristic to control audio volume. */ public class VolumeCharacteristic extends IntegerCharacteristic implements EventableCharacteristic { - public static final int DEFAULT_MIN_VALUE = 0; - public static final int DEFAULT_MAX_VALUE = 100; public VolumeCharacteristic( - int minValue, - int maxValue, Supplier> getter, ExceptionalConsumer setter, Consumer subscriber, @@ -24,20 +20,12 @@ public VolumeCharacteristic( super( "00000119-0000-1000-8000-0026BB765291", "volume", - minValue, - maxValue, + 0, + 100, "percentage", Optional.of(getter), Optional.of(setter), Optional.of(subscriber), Optional.of(unsubscriber)); } - - public VolumeCharacteristic( - Supplier> getter, - ExceptionalConsumer setter, - Consumer subscriber, - Runnable unsubscriber) { - this(DEFAULT_MIN_VALUE, DEFAULT_MAX_VALUE, getter, setter, subscriber, unsubscriber); - } } diff --git a/src/main/java/io/github/hapjava/characteristics/impl/battery/BatteryLevelCharacteristic.java b/src/main/java/io/github/hapjava/characteristics/impl/battery/BatteryLevelCharacteristic.java index ae7097ccd..0fa56ff40 100644 --- a/src/main/java/io/github/hapjava/characteristics/impl/battery/BatteryLevelCharacteristic.java +++ b/src/main/java/io/github/hapjava/characteristics/impl/battery/BatteryLevelCharacteristic.java @@ -11,31 +11,20 @@ /** This characteristic describes the current level of the battery. */ public class BatteryLevelCharacteristic extends IntegerCharacteristic implements EventableCharacteristic { - public static final int DEFAULT_MIN_VALUE = 0; - public static final int DEFAULT_MAX_VALUE = 100; public BatteryLevelCharacteristic( - int minValue, - int maxValue, Supplier> getter, Consumer subscriber, Runnable unsubscriber) { super( "00000068-0000-1000-8000-0026BB765291", "battery level", - minValue, - maxValue, + 0, + 100, "%", Optional.of(getter), Optional.empty(), Optional.of(subscriber), Optional.of(unsubscriber)); } - - public BatteryLevelCharacteristic( - Supplier> getter, - Consumer subscriber, - Runnable unsubscriber) { - this(DEFAULT_MIN_VALUE, DEFAULT_MAX_VALUE, getter, subscriber, unsubscriber); - } } diff --git a/src/main/java/io/github/hapjava/characteristics/impl/common/WaterLavelCharacteristic.java b/src/main/java/io/github/hapjava/characteristics/impl/common/WaterLavelCharacteristic.java index d9d29bac7..dda11b087 100644 --- a/src/main/java/io/github/hapjava/characteristics/impl/common/WaterLavelCharacteristic.java +++ b/src/main/java/io/github/hapjava/characteristics/impl/common/WaterLavelCharacteristic.java @@ -11,34 +11,21 @@ /** This characteristic describes the water level. */ public class WaterLavelCharacteristic extends FloatCharacteristic implements EventableCharacteristic { - public static final double DEFAULT_MIN_VALUE = 0; - public static final double DEFAULT_MAX_VALUE = 100; - public static final double DEFAULT_STEP = 1; public WaterLavelCharacteristic( - double minValue, - double maxValue, - double minStep, Supplier> getter, Consumer subscriber, Runnable unsubscriber) { super( "000000B5-0000-1000-8000-0026BB765291", "water level", - minValue, - maxValue, - minStep, + 0, + 100, + 1, "%", Optional.of(getter), Optional.empty(), Optional.of(subscriber), Optional.of(unsubscriber)); } - - public WaterLavelCharacteristic( - Supplier> getter, - Consumer subscriber, - Runnable unsubscriber) { - this(DEFAULT_MIN_VALUE, DEFAULT_MAX_VALUE, DEFAULT_STEP, getter, subscriber, unsubscriber); - } } diff --git a/src/main/java/io/github/hapjava/characteristics/impl/filtermaintenance/FilterLifeLevelCharacteristic.java b/src/main/java/io/github/hapjava/characteristics/impl/filtermaintenance/FilterLifeLevelCharacteristic.java index 6213769c9..29cdf8d6e 100644 --- a/src/main/java/io/github/hapjava/characteristics/impl/filtermaintenance/FilterLifeLevelCharacteristic.java +++ b/src/main/java/io/github/hapjava/characteristics/impl/filtermaintenance/FilterLifeLevelCharacteristic.java @@ -10,34 +10,21 @@ public class FilterLifeLevelCharacteristic extends FloatCharacteristic implements EventableCharacteristic { - public static final double DEFAULT_MIN_VALUE = 0; - public static final double DEFAULT_MAX_VALUE = 100; - public static final double DEFAULT_STEP = 1; public FilterLifeLevelCharacteristic( - double minValue, - double maxValue, - double minStep, Supplier> getter, Consumer subscriber, Runnable unsubscriber) { super( "000000AB-0000-1000-8000-0026BB765291", "Filter Life Level", - minValue, - maxValue, - minStep, + 0, + 100, + 1, "%", Optional.of(getter), Optional.empty(), Optional.of(subscriber), Optional.of(unsubscriber)); } - - public FilterLifeLevelCharacteristic( - Supplier> getter, - Consumer subscriber, - Runnable unsubscriber) { - this(DEFAULT_MIN_VALUE, DEFAULT_MAX_VALUE, DEFAULT_STEP, getter, subscriber, unsubscriber); - } } diff --git a/src/main/java/io/github/hapjava/characteristics/impl/humidifier/HumidityDehumidifierThresholdCharacteristic.java b/src/main/java/io/github/hapjava/characteristics/impl/humidifier/HumidityDehumidifierThresholdCharacteristic.java index 84a31fe24..b8a4ca569 100644 --- a/src/main/java/io/github/hapjava/characteristics/impl/humidifier/HumidityDehumidifierThresholdCharacteristic.java +++ b/src/main/java/io/github/hapjava/characteristics/impl/humidifier/HumidityDehumidifierThresholdCharacteristic.java @@ -13,14 +13,8 @@ * turns on. */ public class HumidityDehumidifierThresholdCharacteristic extends FloatCharacteristic { - public static final double DEFAULT_MIN_VALUE = 0; - public static final double DEFAULT_MAX_VALUE = 100; - public static final double DEFAULT_STEP = 1; public HumidityDehumidifierThresholdCharacteristic( - double minValue, - double maxValue, - double minStep, Supplier> getter, ExceptionalConsumer setter, Consumer subscriber, @@ -28,28 +22,13 @@ public HumidityDehumidifierThresholdCharacteristic( super( "000000C9-0000-1000-8000-0026BB765291", "humidity threshold dehumidifier", - minValue, - maxValue, - minStep, + 0, + 100, + 1, "%", Optional.of(getter), Optional.of(setter), Optional.of(subscriber), Optional.of(unsubscriber)); } - - public HumidityDehumidifierThresholdCharacteristic( - Supplier> getter, - ExceptionalConsumer setter, - Consumer subscriber, - Runnable unsubscriber) { - this( - DEFAULT_MIN_VALUE, - DEFAULT_MAX_VALUE, - DEFAULT_STEP, - getter, - setter, - subscriber, - unsubscriber); - } } diff --git a/src/main/java/io/github/hapjava/characteristics/impl/humidifier/HumidityHumidifierThresholdCharacteristic.java b/src/main/java/io/github/hapjava/characteristics/impl/humidifier/HumidityHumidifierThresholdCharacteristic.java index 14b78bde1..2ee8adbf2 100644 --- a/src/main/java/io/github/hapjava/characteristics/impl/humidifier/HumidityHumidifierThresholdCharacteristic.java +++ b/src/main/java/io/github/hapjava/characteristics/impl/humidifier/HumidityHumidifierThresholdCharacteristic.java @@ -13,14 +13,8 @@ * turns on. */ public class HumidityHumidifierThresholdCharacteristic extends FloatCharacteristic { - public static final double DEFAULT_MIN_VALUE = 0; - public static final double DEFAULT_MAX_VALUE = 100; - public static final double DEFAULT_STEP = 1; public HumidityHumidifierThresholdCharacteristic( - double minValue, - double maxValue, - double minStep, Supplier> getter, ExceptionalConsumer setter, Consumer subscriber, @@ -28,28 +22,13 @@ public HumidityHumidifierThresholdCharacteristic( super( "000000CA-0000-1000-8000-0026BB765291", "humidity threshold humidifier", - minValue, - maxValue, - minStep, + 0, + 100, + 1, "%", Optional.of(getter), Optional.of(setter), Optional.of(subscriber), Optional.of(unsubscriber)); } - - public HumidityHumidifierThresholdCharacteristic( - Supplier> getter, - ExceptionalConsumer setter, - Consumer subscriber, - Runnable unsubscriber) { - this( - DEFAULT_MIN_VALUE, - DEFAULT_MAX_VALUE, - DEFAULT_STEP, - getter, - setter, - subscriber, - unsubscriber); - } } diff --git a/src/main/java/io/github/hapjava/characteristics/impl/humiditysensor/CurrentRelativeHumidityCharacteristic.java b/src/main/java/io/github/hapjava/characteristics/impl/humiditysensor/CurrentRelativeHumidityCharacteristic.java index 7ce18fb46..be77125b6 100644 --- a/src/main/java/io/github/hapjava/characteristics/impl/humiditysensor/CurrentRelativeHumidityCharacteristic.java +++ b/src/main/java/io/github/hapjava/characteristics/impl/humiditysensor/CurrentRelativeHumidityCharacteristic.java @@ -9,34 +9,21 @@ /** This characteristic describes the current relative humidity. */ public class CurrentRelativeHumidityCharacteristic extends FloatCharacteristic { - public static final double DEFAULT_MIN_VALUE = 0; - public static final double DEFAULT_MAX_VALUE = 100; - public static final double DEFAULT_STEP = 1; public CurrentRelativeHumidityCharacteristic( - double minValue, - double maxValue, - double minStep, Supplier> getter, Consumer subscriber, Runnable unsubscriber) { super( "00000010-0000-1000-8000-0026BB765291", "Current Relative Humidity", - minValue, - maxValue, - minStep, + 0, + 100, + 1, "%", Optional.of(getter), Optional.empty(), Optional.of(subscriber), Optional.of(unsubscriber)); } - - public CurrentRelativeHumidityCharacteristic( - Supplier> getter, - Consumer subscriber, - Runnable unsubscriber) { - this(DEFAULT_MIN_VALUE, DEFAULT_MAX_VALUE, DEFAULT_STEP, getter, subscriber, unsubscriber); - } } diff --git a/src/main/java/io/github/hapjava/characteristics/impl/humiditysensor/TargetRelativeHumidityCharacteristic.java b/src/main/java/io/github/hapjava/characteristics/impl/humiditysensor/TargetRelativeHumidityCharacteristic.java index 600ca0f7c..ab8ad7e29 100644 --- a/src/main/java/io/github/hapjava/characteristics/impl/humiditysensor/TargetRelativeHumidityCharacteristic.java +++ b/src/main/java/io/github/hapjava/characteristics/impl/humiditysensor/TargetRelativeHumidityCharacteristic.java @@ -10,14 +10,8 @@ /** This characteristic describes the target relative humidity. */ public class TargetRelativeHumidityCharacteristic extends FloatCharacteristic { - public static final double DEFAULT_MIN_VALUE = 0; - public static final double DEFAULT_MAX_VALUE = 100; - public static final double DEFAULT_STEP = 1; public TargetRelativeHumidityCharacteristic( - double minValue, - double maxValue, - double minStep, Supplier> getter, ExceptionalConsumer setter, Consumer subscriber, @@ -25,28 +19,13 @@ public TargetRelativeHumidityCharacteristic( super( "00000034-0000-1000-8000-0026BB765291", "Target Relative Humidity", - minValue, - maxValue, - minStep, + 0, + 100, + 1, "%", Optional.of(getter), Optional.of(setter), Optional.of(subscriber), Optional.of(unsubscriber)); } - - public TargetRelativeHumidityCharacteristic( - Supplier> getter, - ExceptionalConsumer setter, - Consumer subscriber, - Runnable unsubscriber) { - this( - DEFAULT_MIN_VALUE, - DEFAULT_MAX_VALUE, - DEFAULT_STEP, - getter, - setter, - subscriber, - unsubscriber); - } } diff --git a/src/main/java/io/github/hapjava/characteristics/impl/lightbulb/BrightnessCharacteristic.java b/src/main/java/io/github/hapjava/characteristics/impl/lightbulb/BrightnessCharacteristic.java index b68cb914b..693e42efc 100644 --- a/src/main/java/io/github/hapjava/characteristics/impl/lightbulb/BrightnessCharacteristic.java +++ b/src/main/java/io/github/hapjava/characteristics/impl/lightbulb/BrightnessCharacteristic.java @@ -15,12 +15,8 @@ */ public class BrightnessCharacteristic extends IntegerCharacteristic implements EventableCharacteristic { - public static final int DEFAULT_MIN_VALUE = 0; - public static final int DEFAULT_MAX_VALUE = 100; public BrightnessCharacteristic( - int minValue, - int maxValue, Supplier> getter, ExceptionalConsumer setter, Consumer subscriber, @@ -28,20 +24,12 @@ public BrightnessCharacteristic( super( "00000008-0000-1000-8000-0026BB765291", "level of brightness", - minValue, - maxValue, + 0, + 100, "%", Optional.of(getter), Optional.of(setter), Optional.of(subscriber), Optional.of(unsubscriber)); } - - public BrightnessCharacteristic( - Supplier> getter, - ExceptionalConsumer setter, - Consumer subscriber, - Runnable unsubscriber) { - this(DEFAULT_MIN_VALUE, DEFAULT_MAX_VALUE, getter, setter, subscriber, unsubscriber); - } } diff --git a/src/main/java/io/github/hapjava/characteristics/impl/lightbulb/HueCharacteristic.java b/src/main/java/io/github/hapjava/characteristics/impl/lightbulb/HueCharacteristic.java index f41a92319..7a00816bc 100644 --- a/src/main/java/io/github/hapjava/characteristics/impl/lightbulb/HueCharacteristic.java +++ b/src/main/java/io/github/hapjava/characteristics/impl/lightbulb/HueCharacteristic.java @@ -10,14 +10,7 @@ /** This characteristic describes hue or color. */ public class HueCharacteristic extends FloatCharacteristic { - public static final double DEFAULT_MIN_VALUE = 0; - public static final double DEFAULT_MAX_VALUE = 360; - public static final double DEFAULT_STEP = 1; - public HueCharacteristic( - double minValue, - double maxValue, - double minStep, Supplier> getter, ExceptionalConsumer setter, Consumer subscriber, @@ -25,28 +18,13 @@ public HueCharacteristic( super( "00000013-0000-1000-8000-0026BB765291", "hue or color", - minValue, - maxValue, - minStep, + 0, + 360, + 1, "arcdegrees", Optional.of(getter), Optional.of(setter), Optional.of(subscriber), Optional.of(unsubscriber)); } - - public HueCharacteristic( - Supplier> getter, - ExceptionalConsumer setter, - Consumer subscriber, - Runnable unsubscriber) { - this( - DEFAULT_MIN_VALUE, - DEFAULT_MAX_VALUE, - DEFAULT_STEP, - getter, - setter, - subscriber, - unsubscriber); - } } diff --git a/src/main/java/io/github/hapjava/characteristics/impl/lightbulb/SaturationCharacteristic.java b/src/main/java/io/github/hapjava/characteristics/impl/lightbulb/SaturationCharacteristic.java index 5d2f7033b..90694ef98 100644 --- a/src/main/java/io/github/hapjava/characteristics/impl/lightbulb/SaturationCharacteristic.java +++ b/src/main/java/io/github/hapjava/characteristics/impl/lightbulb/SaturationCharacteristic.java @@ -12,14 +12,8 @@ /** This characteristic describes color saturation. */ public class SaturationCharacteristic extends FloatCharacteristic implements EventableCharacteristic { - public static final double DEFAULT_MIN_VALUE = 0; - public static final double DEFAULT_MAX_VALUE = 100; - public static final double DEFAULT_STEP = 1; public SaturationCharacteristic( - double minValue, - double maxValue, - double minStep, Supplier> getter, ExceptionalConsumer setter, Consumer subscriber, @@ -27,28 +21,13 @@ public SaturationCharacteristic( super( "0000002F-0000-1000-8000-0026BB765291", "color saturation", - minValue, - maxValue, - minStep, + 0, + 100, + 1, "%", Optional.of(getter), Optional.of(setter), Optional.of(subscriber), Optional.of(unsubscriber)); } - - public SaturationCharacteristic( - Supplier> getter, - ExceptionalConsumer setter, - Consumer subscriber, - Runnable unsubscriber) { - this( - DEFAULT_MIN_VALUE, - DEFAULT_MAX_VALUE, - DEFAULT_STEP, - getter, - setter, - subscriber, - unsubscriber); - } } diff --git a/src/main/java/io/github/hapjava/characteristics/impl/windowcovering/CurrentPositionCharacteristic.java b/src/main/java/io/github/hapjava/characteristics/impl/windowcovering/CurrentPositionCharacteristic.java index e9ed063c8..d51614615 100644 --- a/src/main/java/io/github/hapjava/characteristics/impl/windowcovering/CurrentPositionCharacteristic.java +++ b/src/main/java/io/github/hapjava/characteristics/impl/windowcovering/CurrentPositionCharacteristic.java @@ -11,31 +11,20 @@ /** This characteristic describes the current position of accessories. */ public class CurrentPositionCharacteristic extends IntegerCharacteristic implements EventableCharacteristic { - public static final int DEFAULT_MIN_VALUE = 0; - public static final int DEFAULT_MAX_VALUE = 100; public CurrentPositionCharacteristic( - int minValue, - int maxValue, Supplier> getter, Consumer subscriber, Runnable unsubscriber) { super( "0000006D-0000-1000-8000-0026BB765291", "current position", - minValue, - maxValue, + 0, + 100, "%", Optional.of(getter), Optional.empty(), Optional.of(subscriber), Optional.of(unsubscriber)); } - - public CurrentPositionCharacteristic( - Supplier> getter, - Consumer subscriber, - Runnable unsubscriber) { - this(DEFAULT_MIN_VALUE, DEFAULT_MAX_VALUE, getter, subscriber, unsubscriber); - } } diff --git a/src/main/java/io/github/hapjava/characteristics/impl/windowcovering/TargetPositionCharacteristic.java b/src/main/java/io/github/hapjava/characteristics/impl/windowcovering/TargetPositionCharacteristic.java index 82d06c4b2..6398a0b37 100644 --- a/src/main/java/io/github/hapjava/characteristics/impl/windowcovering/TargetPositionCharacteristic.java +++ b/src/main/java/io/github/hapjava/characteristics/impl/windowcovering/TargetPositionCharacteristic.java @@ -12,12 +12,8 @@ /** This characteristic describes the target position of accessories like door, window, blinds. */ public class TargetPositionCharacteristic extends IntegerCharacteristic implements EventableCharacteristic { - public static final int DEFAULT_MIN_VALUE = 0; - public static final int DEFAULT_MAX_VALUE = 100; public TargetPositionCharacteristic( - int minValue, - int maxValue, Supplier> getter, ExceptionalConsumer setter, Consumer subscriber, @@ -25,20 +21,12 @@ public TargetPositionCharacteristic( super( "0000007C-0000-1000-8000-0026BB765291", "target position", - minValue, - maxValue, + 0, + 100, "%", Optional.of(getter), Optional.of(setter), Optional.of(subscriber), Optional.of(unsubscriber)); } - - public TargetPositionCharacteristic( - Supplier> getter, - ExceptionalConsumer setter, - Consumer subscriber, - Runnable unsubscriber) { - this(DEFAULT_MIN_VALUE, DEFAULT_MAX_VALUE, getter, setter, subscriber, unsubscriber); - } } diff --git a/src/test/java/io/github/hapjava/characteristics/impl/CustomRangeCharacteristicsTest.java b/src/test/java/io/github/hapjava/characteristics/impl/CustomRangeCharacteristicsTest.java deleted file mode 100644 index 800719d6d..000000000 --- a/src/test/java/io/github/hapjava/characteristics/impl/CustomRangeCharacteristicsTest.java +++ /dev/null @@ -1,253 +0,0 @@ -package io.github.hapjava.characteristics.impl; - -import static org.assertj.core.api.Assertions.assertThat; - -import io.github.hapjava.characteristics.Characteristic; -import io.github.hapjava.characteristics.impl.audio.VolumeCharacteristic; -import io.github.hapjava.characteristics.impl.battery.BatteryLevelCharacteristic; -import io.github.hapjava.characteristics.impl.common.WaterLavelCharacteristic; -import io.github.hapjava.characteristics.impl.filtermaintenance.FilterLifeLevelCharacteristic; -import io.github.hapjava.characteristics.impl.humidifier.HumidityDehumidifierThresholdCharacteristic; -import io.github.hapjava.characteristics.impl.humidifier.HumidityHumidifierThresholdCharacteristic; -import io.github.hapjava.characteristics.impl.humiditysensor.CurrentRelativeHumidityCharacteristic; -import io.github.hapjava.characteristics.impl.humiditysensor.TargetRelativeHumidityCharacteristic; -import io.github.hapjava.characteristics.impl.lightbulb.BrightnessCharacteristic; -import io.github.hapjava.characteristics.impl.lightbulb.HueCharacteristic; -import io.github.hapjava.characteristics.impl.lightbulb.SaturationCharacteristic; -import io.github.hapjava.characteristics.impl.slat.CurrentTiltAngleCharacteristic; -import io.github.hapjava.characteristics.impl.slat.TargetTiltAngleCharacteristic; -import io.github.hapjava.characteristics.impl.windowcovering.CurrentHorizontalTiltAngleCharacteristic; -import io.github.hapjava.characteristics.impl.windowcovering.CurrentPositionCharacteristic; -import io.github.hapjava.characteristics.impl.windowcovering.CurrentVerticalTiltAngleCharacteristic; -import io.github.hapjava.characteristics.impl.windowcovering.TargetHorizontalTiltAngleCharacteristic; -import io.github.hapjava.characteristics.impl.windowcovering.TargetPositionCharacteristic; -import io.github.hapjava.characteristics.impl.windowcovering.TargetVerticalTiltAngleCharacteristic; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.CompletableFuture; -import javax.json.JsonObject; -import org.junit.Test; - -/** Custom min/max support, see https://github.com/hap-java/HAP-Java/issues/162 */ -public class CustomRangeCharacteristicsTest { - - /** Serialized output of the default constructors, captured before custom ranges were added. */ - private static final List DEFAULT_CONSTRUCTORS = - Arrays.asList( - Case.of( - "BatteryLevelCharacteristic", - new BatteryLevelCharacteristic( - () -> CompletableFuture.completedFuture(50), cb -> {}, () -> {}), - "{\"iid\":7,\"type\":\"68\",\"perms\":[\"pr\",\"ev\"],\"format\":\"int\",\"value\":50,\"minValue\":0,\"maxValue\":100,\"minStep\":1,\"unit\":\"%\"}"), - Case.of( - "BrightnessCharacteristic", - new BrightnessCharacteristic( - () -> CompletableFuture.completedFuture(50), v -> {}, cb -> {}, () -> {}), - "{\"iid\":7,\"type\":\"8\",\"perms\":[\"pr\",\"pw\",\"ev\"],\"format\":\"int\",\"value\":50,\"minValue\":0,\"maxValue\":100,\"minStep\":1,\"unit\":\"%\"}"), - Case.of( - "CurrentPositionCharacteristic", - new CurrentPositionCharacteristic( - () -> CompletableFuture.completedFuture(50), cb -> {}, () -> {}), - "{\"iid\":7,\"type\":\"6D\",\"perms\":[\"pr\",\"ev\"],\"format\":\"int\",\"value\":50,\"minValue\":0,\"maxValue\":100,\"minStep\":1,\"unit\":\"%\"}"), - Case.of( - "TargetPositionCharacteristic", - new TargetPositionCharacteristic( - () -> CompletableFuture.completedFuture(50), v -> {}, cb -> {}, () -> {}), - "{\"iid\":7,\"type\":\"7C\",\"perms\":[\"pr\",\"pw\",\"ev\"],\"format\":\"int\",\"value\":50,\"minValue\":0,\"maxValue\":100,\"minStep\":1,\"unit\":\"%\"}"), - Case.of( - "VolumeCharacteristic", - new VolumeCharacteristic( - () -> CompletableFuture.completedFuture(50), v -> {}, cb -> {}, () -> {}), - "{\"iid\":7,\"type\":\"119\",\"perms\":[\"pr\",\"pw\",\"ev\"],\"format\":\"int\",\"value\":50,\"minValue\":0,\"maxValue\":100,\"minStep\":1,\"unit\":\"percentage\"}"), - Case.of( - "CurrentTiltAngleCharacteristic", - new CurrentTiltAngleCharacteristic( - () -> CompletableFuture.completedFuture(50), cb -> {}, () -> {}), - "{\"iid\":7,\"type\":\"C1\",\"perms\":[\"pr\",\"ev\"],\"format\":\"int\",\"value\":50,\"minValue\":-90,\"maxValue\":90,\"minStep\":1,\"unit\":\"arcdegrees\"}"), - Case.of( - "TargetTiltAngleCharacteristic", - new TargetTiltAngleCharacteristic( - () -> CompletableFuture.completedFuture(50), v -> {}, cb -> {}, () -> {}), - "{\"iid\":7,\"type\":\"C2\",\"perms\":[\"pr\",\"pw\",\"ev\"],\"format\":\"int\",\"value\":50,\"minValue\":-90,\"maxValue\":90,\"minStep\":1,\"unit\":\"arcdegrees\"}"), - Case.of( - "CurrentHorizontalTiltAngleCharacteristic", - new CurrentHorizontalTiltAngleCharacteristic( - () -> CompletableFuture.completedFuture(50), cb -> {}, () -> {}), - "{\"iid\":7,\"type\":\"6C\",\"perms\":[\"pr\",\"ev\"],\"format\":\"int\",\"value\":50,\"minValue\":-90,\"maxValue\":90,\"minStep\":1,\"unit\":\"arcdegrees\"}"), - Case.of( - "TargetHorizontalTiltAngleCharacteristic", - new TargetHorizontalTiltAngleCharacteristic( - () -> CompletableFuture.completedFuture(50), v -> {}, cb -> {}, () -> {}), - "{\"iid\":7,\"type\":\"7B\",\"perms\":[\"pr\",\"pw\",\"ev\"],\"format\":\"int\",\"value\":50,\"minValue\":-90,\"maxValue\":90,\"minStep\":1,\"unit\":\"arcdegrees\"}"), - Case.of( - "CurrentVerticalTiltAngleCharacteristic", - new CurrentVerticalTiltAngleCharacteristic( - () -> CompletableFuture.completedFuture(50), cb -> {}, () -> {}), - "{\"iid\":7,\"type\":\"6E\",\"perms\":[\"pr\",\"ev\"],\"format\":\"int\",\"value\":50,\"minValue\":-90,\"maxValue\":90,\"minStep\":1,\"unit\":\"arcdegrees\"}"), - Case.of( - "TargetVerticalTiltAngleCharacteristic", - new TargetVerticalTiltAngleCharacteristic( - () -> CompletableFuture.completedFuture(50), v -> {}, cb -> {}, () -> {}), - "{\"iid\":7,\"type\":\"7D\",\"perms\":[\"pr\",\"pw\",\"ev\"],\"format\":\"int\",\"value\":50,\"minValue\":-90,\"maxValue\":90,\"minStep\":1,\"unit\":\"arcdegrees\"}"), - Case.of( - "CurrentRelativeHumidityCharacteristic", - new CurrentRelativeHumidityCharacteristic( - () -> CompletableFuture.completedFuture(50.0), cb -> {}, () -> {}), - "{\"iid\":7,\"type\":\"10\",\"perms\":[\"pr\",\"ev\"],\"format\":\"float\",\"value\":50.0,\"minValue\":0.0,\"maxValue\":100.0,\"minStep\":1.0,\"unit\":\"%\"}"), - Case.of( - "TargetRelativeHumidityCharacteristic", - new TargetRelativeHumidityCharacteristic( - () -> CompletableFuture.completedFuture(50.0), v -> {}, cb -> {}, () -> {}), - "{\"iid\":7,\"type\":\"34\",\"perms\":[\"pr\",\"pw\",\"ev\"],\"format\":\"float\",\"value\":50.0,\"minValue\":0.0,\"maxValue\":100.0,\"minStep\":1.0,\"unit\":\"%\"}"), - Case.of( - "FilterLifeLevelCharacteristic", - new FilterLifeLevelCharacteristic( - () -> CompletableFuture.completedFuture(50.0), cb -> {}, () -> {}), - "{\"iid\":7,\"type\":\"AB\",\"perms\":[\"pr\",\"ev\"],\"format\":\"float\",\"value\":50.0,\"minValue\":0.0,\"maxValue\":100.0,\"minStep\":1.0,\"unit\":\"%\"}"), - Case.of( - "HueCharacteristic", - new HueCharacteristic( - () -> CompletableFuture.completedFuture(50.0), v -> {}, cb -> {}, () -> {}), - "{\"iid\":7,\"type\":\"13\",\"perms\":[\"pr\",\"pw\",\"ev\"],\"format\":\"float\",\"value\":50.0,\"minValue\":0.0,\"maxValue\":360.0,\"minStep\":1.0,\"unit\":\"arcdegrees\"}"), - Case.of( - "SaturationCharacteristic", - new SaturationCharacteristic( - () -> CompletableFuture.completedFuture(50.0), v -> {}, cb -> {}, () -> {}), - "{\"iid\":7,\"type\":\"2F\",\"perms\":[\"pr\",\"pw\",\"ev\"],\"format\":\"float\",\"value\":50.0,\"minValue\":0.0,\"maxValue\":100.0,\"minStep\":1.0,\"unit\":\"%\"}"), - Case.of( - "HumidityDehumidifierThresholdCharacteristic", - new HumidityDehumidifierThresholdCharacteristic( - () -> CompletableFuture.completedFuture(50.0), v -> {}, cb -> {}, () -> {}), - "{\"iid\":7,\"type\":\"C9\",\"perms\":[\"pr\",\"pw\",\"ev\"],\"format\":\"float\",\"value\":50.0,\"minValue\":0.0,\"maxValue\":100.0,\"minStep\":1.0,\"unit\":\"%\"}"), - Case.of( - "HumidityHumidifierThresholdCharacteristic", - new HumidityHumidifierThresholdCharacteristic( - () -> CompletableFuture.completedFuture(50.0), v -> {}, cb -> {}, () -> {}), - "{\"iid\":7,\"type\":\"CA\",\"perms\":[\"pr\",\"pw\",\"ev\"],\"format\":\"float\",\"value\":50.0,\"minValue\":0.0,\"maxValue\":100.0,\"minStep\":1.0,\"unit\":\"%\"}"), - Case.of( - "WaterLavelCharacteristic", - new WaterLavelCharacteristic( - () -> CompletableFuture.completedFuture(50.0), cb -> {}, () -> {}), - "{\"iid\":7,\"type\":\"B5\",\"perms\":[\"pr\",\"ev\"],\"format\":\"float\",\"value\":50.0,\"minValue\":0.0,\"maxValue\":100.0,\"minStep\":1.0,\"unit\":\"%\"}")); - - @Test - public void defaultConstructorsKeepTheirSerializedOutput() { - for (Case c : DEFAULT_CONSTRUCTORS) { - assertThat(c.characteristic.toJson(7).join().toString()).as(c.name).isEqualTo(c.expectedJson); - } - } - - @Test - public void integerCharacteristicsAdvertiseCustomRange() { - for (Characteristic c : - Arrays.asList( - new BatteryLevelCharacteristic( - 10, 20, () -> CompletableFuture.completedFuture(50), cb -> {}, () -> {}), - new BrightnessCharacteristic( - 10, 20, () -> CompletableFuture.completedFuture(50), v -> {}, cb -> {}, () -> {}), - new CurrentPositionCharacteristic( - 10, 20, () -> CompletableFuture.completedFuture(50), cb -> {}, () -> {}), - new TargetPositionCharacteristic( - 10, 20, () -> CompletableFuture.completedFuture(50), v -> {}, cb -> {}, () -> {}), - new VolumeCharacteristic( - 10, 20, () -> CompletableFuture.completedFuture(50), v -> {}, cb -> {}, () -> {}), - new CurrentTiltAngleCharacteristic( - 10, 20, () -> CompletableFuture.completedFuture(50), cb -> {}, () -> {}), - new TargetTiltAngleCharacteristic( - 10, 20, () -> CompletableFuture.completedFuture(50), v -> {}, cb -> {}, () -> {}), - new CurrentHorizontalTiltAngleCharacteristic( - 10, 20, () -> CompletableFuture.completedFuture(50), cb -> {}, () -> {}), - new TargetHorizontalTiltAngleCharacteristic( - 10, 20, () -> CompletableFuture.completedFuture(50), v -> {}, cb -> {}, () -> {}), - new CurrentVerticalTiltAngleCharacteristic( - 10, 20, () -> CompletableFuture.completedFuture(50), cb -> {}, () -> {}), - new TargetVerticalTiltAngleCharacteristic( - 10, - 20, - () -> CompletableFuture.completedFuture(50), - v -> {}, - cb -> {}, - () -> {}))) { - JsonObject json = c.toJson(7).join(); - String name = c.getClass().getSimpleName(); - assertThat(json.getInt("minValue")).as(name).isEqualTo(10); - assertThat(json.getInt("maxValue")).as(name).isEqualTo(20); - assertThat(json.getInt("minStep")).as(name).isEqualTo(1); - } - } - - @Test - public void floatCharacteristicsAdvertiseCustomRangeAndClampToIt() { - for (Characteristic c : - Arrays.asList( - new CurrentRelativeHumidityCharacteristic( - 10, 20, 0.5, () -> CompletableFuture.completedFuture(50.0), cb -> {}, () -> {}), - new TargetRelativeHumidityCharacteristic( - 10, - 20, - 0.5, - () -> CompletableFuture.completedFuture(50.0), - v -> {}, - cb -> {}, - () -> {}), - new FilterLifeLevelCharacteristic( - 10, 20, 0.5, () -> CompletableFuture.completedFuture(50.0), cb -> {}, () -> {}), - new HueCharacteristic( - 10, - 20, - 0.5, - () -> CompletableFuture.completedFuture(50.0), - v -> {}, - cb -> {}, - () -> {}), - new SaturationCharacteristic( - 10, - 20, - 0.5, - () -> CompletableFuture.completedFuture(50.0), - v -> {}, - cb -> {}, - () -> {}), - new HumidityDehumidifierThresholdCharacteristic( - 10, - 20, - 0.5, - () -> CompletableFuture.completedFuture(50.0), - v -> {}, - cb -> {}, - () -> {}), - new HumidityHumidifierThresholdCharacteristic( - 10, - 20, - 0.5, - () -> CompletableFuture.completedFuture(50.0), - v -> {}, - cb -> {}, - () -> {}), - new WaterLavelCharacteristic( - 10, 20, 0.5, () -> CompletableFuture.completedFuture(50.0), cb -> {}, () -> {}))) { - JsonObject json = c.toJson(7).join(); - String name = c.getClass().getSimpleName(); - assertThat(json.getJsonNumber("minValue").doubleValue()).as(name).isEqualTo(10.0); - assertThat(json.getJsonNumber("maxValue").doubleValue()).as(name).isEqualTo(20.0); - assertThat(json.getJsonNumber("minStep").doubleValue()).as(name).isEqualTo(0.5); - assertThat(json.getJsonNumber("value").doubleValue()).as(name).isEqualTo(20.0); - } - } - - private static class Case { - final String name; - final Characteristic characteristic; - final String expectedJson; - - private Case(String name, Characteristic characteristic, String expectedJson) { - this.name = name; - this.characteristic = characteristic; - this.expectedJson = expectedJson; - } - - static Case of(String name, Characteristic characteristic, String expectedJson) { - return new Case(name, characteristic, expectedJson); - } - } -} diff --git a/src/test/java/io/github/hapjava/characteristics/impl/CustomTiltAngleRangeTest.java b/src/test/java/io/github/hapjava/characteristics/impl/CustomTiltAngleRangeTest.java new file mode 100644 index 000000000..dcff74fc3 --- /dev/null +++ b/src/test/java/io/github/hapjava/characteristics/impl/CustomTiltAngleRangeTest.java @@ -0,0 +1,92 @@ +package io.github.hapjava.characteristics.impl; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.github.hapjava.characteristics.Characteristic; +import io.github.hapjava.characteristics.impl.slat.CurrentTiltAngleCharacteristic; +import io.github.hapjava.characteristics.impl.slat.TargetTiltAngleCharacteristic; +import io.github.hapjava.characteristics.impl.windowcovering.CurrentHorizontalTiltAngleCharacteristic; +import io.github.hapjava.characteristics.impl.windowcovering.CurrentVerticalTiltAngleCharacteristic; +import io.github.hapjava.characteristics.impl.windowcovering.TargetHorizontalTiltAngleCharacteristic; +import io.github.hapjava.characteristics.impl.windowcovering.TargetVerticalTiltAngleCharacteristic; +import java.util.Arrays; +import java.util.concurrent.CompletableFuture; +import javax.json.JsonObject; +import org.junit.Test; + +/** Custom tilt angle ranges, see https://github.com/hap-java/HAP-Java/issues/162 */ +public class CustomTiltAngleRangeTest { + + @Test + public void defaultConstructorsKeepTheirSerializedOutput() { + // Serialized output captured before custom ranges were added. + for (Case c : + Arrays.asList( + Case.of( + new CurrentTiltAngleCharacteristic( + () -> CompletableFuture.completedFuture(50), cb -> {}, () -> {}), + "{\"iid\":7,\"type\":\"C1\",\"perms\":[\"pr\",\"ev\"],\"format\":\"int\",\"value\":50,\"minValue\":-90,\"maxValue\":90,\"minStep\":1,\"unit\":\"arcdegrees\"}"), + Case.of( + new TargetTiltAngleCharacteristic( + () -> CompletableFuture.completedFuture(50), v -> {}, cb -> {}, () -> {}), + "{\"iid\":7,\"type\":\"C2\",\"perms\":[\"pr\",\"pw\",\"ev\"],\"format\":\"int\",\"value\":50,\"minValue\":-90,\"maxValue\":90,\"minStep\":1,\"unit\":\"arcdegrees\"}"), + Case.of( + new CurrentHorizontalTiltAngleCharacteristic( + () -> CompletableFuture.completedFuture(50), cb -> {}, () -> {}), + "{\"iid\":7,\"type\":\"6C\",\"perms\":[\"pr\",\"ev\"],\"format\":\"int\",\"value\":50,\"minValue\":-90,\"maxValue\":90,\"minStep\":1,\"unit\":\"arcdegrees\"}"), + Case.of( + new TargetHorizontalTiltAngleCharacteristic( + () -> CompletableFuture.completedFuture(50), v -> {}, cb -> {}, () -> {}), + "{\"iid\":7,\"type\":\"7B\",\"perms\":[\"pr\",\"pw\",\"ev\"],\"format\":\"int\",\"value\":50,\"minValue\":-90,\"maxValue\":90,\"minStep\":1,\"unit\":\"arcdegrees\"}"), + Case.of( + new CurrentVerticalTiltAngleCharacteristic( + () -> CompletableFuture.completedFuture(50), cb -> {}, () -> {}), + "{\"iid\":7,\"type\":\"6E\",\"perms\":[\"pr\",\"ev\"],\"format\":\"int\",\"value\":50,\"minValue\":-90,\"maxValue\":90,\"minStep\":1,\"unit\":\"arcdegrees\"}"), + Case.of( + new TargetVerticalTiltAngleCharacteristic( + () -> CompletableFuture.completedFuture(50), v -> {}, cb -> {}, () -> {}), + "{\"iid\":7,\"type\":\"7D\",\"perms\":[\"pr\",\"pw\",\"ev\"],\"format\":\"int\",\"value\":50,\"minValue\":-90,\"maxValue\":90,\"minStep\":1,\"unit\":\"arcdegrees\"}"))) { + assertThat(c.characteristic.toJson(7).join().toString()) + .as(c.characteristic.getClass().getSimpleName()) + .isEqualTo(c.expected); + } + } + + @Test + public void customRangeIsAdvertised() { + for (Characteristic c : + Arrays.asList( + new CurrentTiltAngleCharacteristic( + 0, 90, () -> CompletableFuture.completedFuture(50), cb -> {}, () -> {}), + new TargetTiltAngleCharacteristic( + 0, 90, () -> CompletableFuture.completedFuture(50), v -> {}, cb -> {}, () -> {}), + new CurrentHorizontalTiltAngleCharacteristic( + 0, 90, () -> CompletableFuture.completedFuture(50), cb -> {}, () -> {}), + new TargetHorizontalTiltAngleCharacteristic( + 0, 90, () -> CompletableFuture.completedFuture(50), v -> {}, cb -> {}, () -> {}), + new CurrentVerticalTiltAngleCharacteristic( + 0, 90, () -> CompletableFuture.completedFuture(50), cb -> {}, () -> {}), + new TargetVerticalTiltAngleCharacteristic( + 0, 90, () -> CompletableFuture.completedFuture(50), v -> {}, cb -> {}, () -> {}))) { + JsonObject json = c.toJson(7).join(); + String name = c.getClass().getSimpleName(); + assertThat(json.getInt("minValue")).as(name).isEqualTo(0); + assertThat(json.getInt("maxValue")).as(name).isEqualTo(90); + assertThat(json.getInt("minStep")).as(name).isEqualTo(1); + } + } + + private static class Case { + final Characteristic characteristic; + final String expected; + + private Case(Characteristic characteristic, String expected) { + this.characteristic = characteristic; + this.expected = expected; + } + + static Case of(Characteristic characteristic, String expected) { + return new Case(characteristic, expected); + } + } +}