]> git.basschouten.com Git - openhab-addons.git/commitdiff
[hue] Fix edge cases for broken lights (#15999)
authorAndrew Fiddian-Green <software@whitebear.ch>
Wed, 6 Dec 2023 14:22:04 +0000 (14:22 +0000)
committerGitHub <noreply@github.com>
Wed, 6 Dec 2023 14:22:04 +0000 (15:22 +0100)
Signed-off-by: Andrew Fiddian-Green <software@whitebear.ch>
bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/api/dto/clip2/OnState.java
bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/api/dto/clip2/Resource.java
bundles/org.openhab.binding.hue/src/test/java/org/openhab/binding/hue/internal/clip2/OnStateDimmingEdgeCaseTest.java [new file with mode: 0644]

index d0ba4056fad0c25193090f65c6989f1db0483010..7907d5dd714d30cb7b113c7bfc1922c0b6c226d6 100644 (file)
@@ -38,7 +38,8 @@ public class OnState {
         throw new DTOPresentButEmptyException("'on' DTO is present but empty");
     }
 
-    public void setOn(boolean on) {
+    public OnState setOn(boolean on) {
         this.on = on;
+        return this;
     }
 }
index c41ce35f94e0127614565b5ff63289070087721b..74676dda213300d3c2b0b813c0a05e824ee7556d 100644 (file)
@@ -205,10 +205,16 @@ public class Resource {
         Dimming dimming = this.dimming;
         if (Objects.nonNull(dimming)) {
             try {
-                // if off the brightness is 0, otherwise it is dimming value
+                // if off the brightness is 0, otherwise it is the larger of dimming value or minimum dimming level
                 OnState on = this.on;
-                double brightness = Objects.nonNull(on) && !on.isOn() ? 0f
-                        : Math.max(0f, Math.min(100f, dimming.getBrightness()));
+                double brightness;
+                if (Objects.nonNull(on) && !on.isOn()) {
+                    brightness = 0f;
+                } else {
+                    Double minimumDimmingLevel = dimming.getMinimumDimmingLevel();
+                    brightness = Math.max(Objects.nonNull(minimumDimmingLevel) ? minimumDimmingLevel
+                            : Dimming.DEFAULT_MINIMUM_DIMMIMG_LEVEL, Math.min(100f, dimming.getBrightness()));
+                }
                 return new PercentType(new BigDecimal(brightness, PERCENT_MATH_CONTEXT));
             } catch (DTOPresentButEmptyException e) {
                 return UnDefType.UNDEF; // indicates the DTO is present but its inner fields are missing
@@ -874,8 +880,9 @@ public class Resource {
         return this;
     }
 
-    public void setOnState(@Nullable OnState on) {
+    public Resource setOnState(@Nullable OnState on) {
         this.on = on;
+        return this;
     }
 
     public Resource setRecallAction(SceneRecallAction recallAction) {
diff --git a/bundles/org.openhab.binding.hue/src/test/java/org/openhab/binding/hue/internal/clip2/OnStateDimmingEdgeCaseTest.java b/bundles/org.openhab.binding.hue/src/test/java/org/openhab/binding/hue/internal/clip2/OnStateDimmingEdgeCaseTest.java
new file mode 100644 (file)
index 0000000..e5d5bd4
--- /dev/null
@@ -0,0 +1,119 @@
+/**
+ * Copyright (c) 2010-2023 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.hue.internal.clip2;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import java.math.BigDecimal;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.junit.jupiter.api.Test;
+import org.openhab.binding.hue.internal.api.dto.clip2.Dimming;
+import org.openhab.binding.hue.internal.api.dto.clip2.OnState;
+import org.openhab.binding.hue.internal.api.dto.clip2.Resource;
+import org.openhab.binding.hue.internal.api.dto.clip2.enums.ResourceType;
+import org.openhab.core.library.types.PercentType;
+import org.openhab.core.types.UnDefType;
+
+/**
+ * JUnit test for edge cases of OnState and Dimming event and cache resources.
+ *
+ * @author Jacob Laursen - Initial contribution
+ */
+@NonNullByDefault
+class OnStateDimmingEdgeCaseTest {
+
+    @Test
+    void getBrightnessStateWhenDimmingMissingReturnNull() {
+        assertThat(createLightResource(true, null).getBrightnessState(), is(equalTo(UnDefType.NULL)));
+    }
+
+    @Test
+    void getBrightnessStateWhenOnAndDimming75ReturnBrightness75() {
+        assertThat(createLightResource(true, 75.0).getBrightnessState(), is(equalTo(new PercentType(75))));
+    }
+
+    @Test
+    void getBrightnessStateWhenOnAndDimming125ReturnBrightness100() {
+        assertThat(createLightResource(true, 125.0).getBrightnessState(), is(equalTo(new PercentType(100))));
+    }
+
+    @Test
+    void getBrightnessStateWhenOffAndDimming100ReturnBrightness0() {
+        assertThat(createLightResource(false, 100.0).getBrightnessState(), is(equalTo(new PercentType(0))));
+    }
+
+    @Test
+    void getBrightnessStateWhenOnStateMissingAndDimming0ReturnMinimumBrightness0() {
+        assertThat(createLightResource(null, 0.0).getBrightnessState(),
+                is(equalTo(new PercentType(new BigDecimal(Dimming.DEFAULT_MINIMUM_DIMMIMG_LEVEL)))));
+    }
+
+    @Test
+    void getBrightnessStateWhenOnStateMissingAndDimming100ReturnBrightness100() {
+        assertThat(createLightResource(null, 100.0).getBrightnessState(), is(equalTo(new PercentType(100))));
+    }
+
+    @Test
+    void getBrightnessStateWhenOnStateMissingAndDimmingMinus1ReturnMinimumBrightness() {
+        assertThat(createLightResource(null, -1.0).getBrightnessState(),
+                is(equalTo(new PercentType(new BigDecimal(Dimming.DEFAULT_MINIMUM_DIMMIMG_LEVEL)))));
+    }
+
+    @Test
+    void getBrightnessStateWhenOnAndDimmingMinus1ReturnMinimumBrightness() {
+        assertThat(createLightResource(true, -1.0).getBrightnessState(),
+                is(equalTo(new PercentType(new BigDecimal(Dimming.DEFAULT_MINIMUM_DIMMIMG_LEVEL)))));
+    }
+
+    @Test
+    void getBrightnessStateWhenOnAndDimming0ReturnMinimumBrightness() {
+        assertThat(createLightResource(true, 0.0).getBrightnessState(),
+                is(equalTo(new PercentType(new BigDecimal(Dimming.DEFAULT_MINIMUM_DIMMIMG_LEVEL)))));
+    }
+
+    @Test
+    void getBrightnessStateWhenOnAndDimming0ReturnCustomMinimumBrightness() {
+        assertThat(createLightResource(true, 0.0, 2.0).getBrightnessState(), is(equalTo(new PercentType(2))));
+    }
+
+    private Resource createLightResource(@Nullable Boolean on, @Nullable Double brightness) {
+        return createLightResource(on, brightness, null);
+    }
+
+    private Resource createLightResource(@Nullable Boolean on, @Nullable Double brightness,
+            @Nullable Double minimumDimmingLevel) {
+        Resource resource = new Resource(ResourceType.LIGHT);
+
+        if (on != null) {
+            OnState onState = new OnState();
+            onState.setOn(on);
+            resource.setOnState(onState);
+        }
+
+        if (brightness != null) {
+            Dimming dimming = new Dimming();
+            dimming.setBrightness(brightness);
+
+            if (minimumDimmingLevel != null) {
+                dimming.setMinimumDimmingLevel(minimumDimmingLevel);
+            }
+
+            resource.setDimming(dimming);
+        }
+
+        return resource;
+    }
+}