From 7160355f4828bb582cee95c1ce015879047ef145 Mon Sep 17 00:00:00 2001 From: Andrew Fiddian-Green Date: Sun, 3 Dec 2023 18:41:58 +0000 Subject: [PATCH 1/4] [hue] sort scene change events Signed-off-by: Andrew Fiddian-Green --- .../api/dto/clip2/helper/Setters.java | 24 ++++++ .../internal/handler/Clip2BridgeHandler.java | 1 + .../internal/clip2/SortSceneEventsTest.java | 77 +++++++++++++++++++ .../src/test/resources/scene_event.json | 46 +++++++++++ 4 files changed, 148 insertions(+) create mode 100644 bundles/org.openhab.binding.hue/src/test/java/org/openhab/binding/hue/internal/clip2/SortSceneEventsTest.java create mode 100644 bundles/org.openhab.binding.hue/src/test/resources/scene_event.json diff --git a/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/api/dto/clip2/helper/Setters.java b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/api/dto/clip2/helper/Setters.java index 35083b09e8f43..c1a15ca2ab678 100644 --- a/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/api/dto/clip2/helper/Setters.java +++ b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/api/dto/clip2/helper/Setters.java @@ -17,6 +17,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.Iterator; +import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Objects; @@ -59,6 +60,16 @@ public class Setters { private static final Set LIGHT_TYPES = Set.of(ResourceType.LIGHT, ResourceType.GROUPED_LIGHT); + + /* + * Comparator to sort Resources so that scene activation resources come last. + */ + private static final Comparator SCENE_ACTIVE_COMPARATOR = new Comparator<>() { + @Override + public int compare(Resource r1, Resource r2) { + return !r1.getSceneActive().orElse(false) ? -1 : 0; + } + }; /** * Setter for Alert field: @@ -398,7 +409,20 @@ public static Collection mergeLightResources(Collection reso iterator.remove(); } } + } + /** + * Sort a list of resources so that scene activation event resources (if any) get + * processed after scene de-activation event resources (if any). + * + * @param resources list of resources to be sorted. + * @return the sorted list with scene activation event resources moved to the end. + */ + public static List sortSceneResources(List resources) { + if (resources.stream().filter(r -> r.getSceneActive().isPresent()).count() < 2) { + return resources; + } + resources.sort(SCENE_ACTIVE_COMPARATOR); return resources; } } diff --git a/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/handler/Clip2BridgeHandler.java b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/handler/Clip2BridgeHandler.java index e6dd7181ea26a..98602854e45e1 100644 --- a/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/handler/Clip2BridgeHandler.java +++ b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/handler/Clip2BridgeHandler.java @@ -535,6 +535,7 @@ private void onResourcesEventTask(List resources) { if (numberOfResources != resources.size()) { logger.debug("onResourcesEventTask() merged to {} resources", resources.size()); } + Setters.sortSceneResources(resources); getThing().getThings().forEach(thing -> { if (thing.getHandler() instanceof Clip2ThingHandler clip2ThingHandler) { resources.forEach(resource -> clip2ThingHandler.onResource(resource)); diff --git a/bundles/org.openhab.binding.hue/src/test/java/org/openhab/binding/hue/internal/clip2/SortSceneEventsTest.java b/bundles/org.openhab.binding.hue/src/test/java/org/openhab/binding/hue/internal/clip2/SortSceneEventsTest.java new file mode 100644 index 0000000000000..dbdf7d8bb6091 --- /dev/null +++ b/bundles/org.openhab.binding.hue/src/test/java/org/openhab/binding/hue/internal/clip2/SortSceneEventsTest.java @@ -0,0 +1,77 @@ +/** + * 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.junit.jupiter.api.Assertions.*; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.time.Instant; +import java.util.List; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.junit.jupiter.api.Test; +import org.openhab.binding.hue.internal.api.dto.clip2.Resource; +import org.openhab.binding.hue.internal.api.dto.clip2.Resources; +import org.openhab.binding.hue.internal.api.dto.clip2.helper.Setters; +import org.openhab.binding.hue.internal.api.serialization.InstantDeserializer; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +/** + * JUnit test for sorting the sequence of scene events in a list. + * + * @author Andrew Fiddian-Green - Initial contribution + */ +@NonNullByDefault +class SortSceneResourcesTest { + + private static final Gson GSON = new GsonBuilder().registerTypeAdapter(Instant.class, new InstantDeserializer()) + .create(); + + private static final String ACTIVE_SCENE_RESOURCE_ID = "ACTIVE00-0000-0000-0000-000000000001"; + + private String loadJson(String fileName) { + try (FileReader file = new FileReader(String.format("src/test/resources/%s.json", fileName)); + BufferedReader reader = new BufferedReader(file)) { + StringBuilder builder = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + builder.append(line).append("\n"); + } + return builder.toString(); + } catch (IOException e) { + fail(e.getMessage()); + } + return ""; + } + + @Test + void testSceneSorting() { + Resources resources = GSON.fromJson(loadJson("scene_event"), Resources.class); + assertNotNull(resources); + List list = resources.getResources(); + assertNotNull(list); + list.forEach(r -> r.markAsSparse()); + + assertEquals(5, list.size()); + assertEquals(ACTIVE_SCENE_RESOURCE_ID, list.get(1).getId()); + + Setters.sortSceneResources(list); + + assertEquals(5, list.size()); + assertEquals(ACTIVE_SCENE_RESOURCE_ID, list.get(4).getId()); + } +} diff --git a/bundles/org.openhab.binding.hue/src/test/resources/scene_event.json b/bundles/org.openhab.binding.hue/src/test/resources/scene_event.json new file mode 100644 index 0000000000000..598372fcab2c8 --- /dev/null +++ b/bundles/org.openhab.binding.hue/src/test/resources/scene_event.json @@ -0,0 +1,46 @@ +{ + "errors": [ + ], + "data": [ + { + "id": "00000000-0000-0000-0000-000000000000", + "id_v1": "/lights/40", + "on": { + "on": false + }, + "type": "light" + }, + { + "id": "ACTIVE00-0000-0000-0000-000000000001", + "id_v1": "/scenes/BK-UE-77VNFHKRi", + "status": { + "active": "static" + }, + "type": "scene" + }, + { + "id": "00000000-0000-0000-0000-000000000002", + "id_v1": "/lights/40", + "on": { + "on": false + }, + "type": "light" + }, + { + "id": "00000000-0000-0000-0000-000000000003", + "id_v1": "/scenes/rULmu6mjOgC4U7I", + "status": { + "active": "inactive" + }, + "type": "scene" + }, + { + "id": "00000000-0000-0000-0000-000000000004", + "id_v1": "/lights/40", + "on": { + "on": false + }, + "type": "light" + } + ] +} From c663c24b3c6ea3338ef3480a0f53b8c452786855 Mon Sep 17 00:00:00 2001 From: Andrew Fiddian-Green Date: Mon, 4 Dec 2023 13:54:54 +0000 Subject: [PATCH 2/4] [hue] tweak comparator; resolve class name conflict Signed-off-by: Andrew Fiddian-Green --- .../binding/hue/internal/api/dto/clip2/helper/Setters.java | 2 +- .../{SortSceneEventsTest.java => SortSceneResourcesTest.java} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename bundles/org.openhab.binding.hue/src/test/java/org/openhab/binding/hue/internal/clip2/{SortSceneEventsTest.java => SortSceneResourcesTest.java} (100%) diff --git a/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/api/dto/clip2/helper/Setters.java b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/api/dto/clip2/helper/Setters.java index c1a15ca2ab678..0b90338cc82cc 100644 --- a/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/api/dto/clip2/helper/Setters.java +++ b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/api/dto/clip2/helper/Setters.java @@ -67,7 +67,7 @@ public class Setters { private static final Comparator SCENE_ACTIVE_COMPARATOR = new Comparator<>() { @Override public int compare(Resource r1, Resource r2) { - return !r1.getSceneActive().orElse(false) ? -1 : 0; + return (r1.getSceneActive().orElse(false) ? 1 : 0) + (r2.getSceneActive().orElse(false) ? -1 : 0); } }; diff --git a/bundles/org.openhab.binding.hue/src/test/java/org/openhab/binding/hue/internal/clip2/SortSceneEventsTest.java b/bundles/org.openhab.binding.hue/src/test/java/org/openhab/binding/hue/internal/clip2/SortSceneResourcesTest.java similarity index 100% rename from bundles/org.openhab.binding.hue/src/test/java/org/openhab/binding/hue/internal/clip2/SortSceneEventsTest.java rename to bundles/org.openhab.binding.hue/src/test/java/org/openhab/binding/hue/internal/clip2/SortSceneResourcesTest.java From babcf6061ebe49967bbc3a0fc123549b15a0ac90 Mon Sep 17 00:00:00 2001 From: Andrew Fiddian-Green Date: Tue, 5 Dec 2023 13:48:04 +0000 Subject: [PATCH 3/4] [hue] fix merge conflict resolution Signed-off-by: Andrew Fiddian-Green --- .../binding/hue/internal/api/dto/clip2/helper/Setters.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/api/dto/clip2/helper/Setters.java b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/api/dto/clip2/helper/Setters.java index 0b90338cc82cc..ae5559c18cf12 100644 --- a/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/api/dto/clip2/helper/Setters.java +++ b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/api/dto/clip2/helper/Setters.java @@ -15,9 +15,9 @@ import java.math.BigDecimal; import java.time.Duration; import java.util.Collection; +import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; -import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Objects; @@ -60,7 +60,7 @@ public class Setters { private static final Set LIGHT_TYPES = Set.of(ResourceType.LIGHT, ResourceType.GROUPED_LIGHT); - + /* * Comparator to sort Resources so that scene activation resources come last. */ @@ -409,6 +409,7 @@ public static Collection mergeLightResources(Collection reso iterator.remove(); } } + return resources; } /** From deeb453d03def671a4ffb559a6c6236cae3ba08a Mon Sep 17 00:00:00 2001 From: Andrew Fiddian-Green Date: Wed, 6 Dec 2023 09:45:57 +0000 Subject: [PATCH 4/4] [hue] adopt reviewer suggestions Signed-off-by: Andrew Fiddian-Green --- .../hue/internal/api/dto/clip2/Resource.java | 7 ++- .../api/dto/clip2/helper/Setters.java | 3 - .../clip2/SortSceneResourcesTest.java | 61 +++++++++---------- .../src/test/resources/scene_event.json | 46 -------------- 4 files changed, 34 insertions(+), 83 deletions(-) delete mode 100644 bundles/org.openhab.binding.hue/src/test/resources/scene_event.json diff --git a/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/api/dto/clip2/Resource.java b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/api/dto/clip2/Resource.java index c41ce35f94e01..05e5f4ca2fa73 100644 --- a/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/api/dto/clip2/Resource.java +++ b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/api/dto/clip2/Resource.java @@ -124,7 +124,7 @@ public Resource(@Nullable ResourceType resourceType) { /** * Check if light or grouped_light resource contains any * relevant fields to process according to its type. - * + * * As an example, {@link #colorTemperature} is relevant for a light * resource because it's needed for updating the color-temperature channels. * @@ -919,6 +919,11 @@ public Resource setType(ResourceType resourceType) { return this; } + public Resource setStatus(@Nullable JsonElement status) { + this.status = status; + return this; + } + @Override public String toString() { String id = this.id; diff --git a/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/api/dto/clip2/helper/Setters.java b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/api/dto/clip2/helper/Setters.java index ae5559c18cf12..9a1a68a7a88d2 100644 --- a/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/api/dto/clip2/helper/Setters.java +++ b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/api/dto/clip2/helper/Setters.java @@ -420,9 +420,6 @@ public static Collection mergeLightResources(Collection reso * @return the sorted list with scene activation event resources moved to the end. */ public static List sortSceneResources(List resources) { - if (resources.stream().filter(r -> r.getSceneActive().isPresent()).count() < 2) { - return resources; - } resources.sort(SCENE_ACTIVE_COMPARATOR); return resources; } diff --git a/bundles/org.openhab.binding.hue/src/test/java/org/openhab/binding/hue/internal/clip2/SortSceneResourcesTest.java b/bundles/org.openhab.binding.hue/src/test/java/org/openhab/binding/hue/internal/clip2/SortSceneResourcesTest.java index dbdf7d8bb6091..b09f07b1a3d3d 100644 --- a/bundles/org.openhab.binding.hue/src/test/java/org/openhab/binding/hue/internal/clip2/SortSceneResourcesTest.java +++ b/bundles/org.openhab.binding.hue/src/test/java/org/openhab/binding/hue/internal/clip2/SortSceneResourcesTest.java @@ -14,21 +14,17 @@ import static org.junit.jupiter.api.Assertions.*; -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.IOException; -import java.time.Instant; +import java.util.ArrayList; import java.util.List; import org.eclipse.jdt.annotation.NonNullByDefault; import org.junit.jupiter.api.Test; import org.openhab.binding.hue.internal.api.dto.clip2.Resource; -import org.openhab.binding.hue.internal.api.dto.clip2.Resources; +import org.openhab.binding.hue.internal.api.dto.clip2.enums.ResourceType; import org.openhab.binding.hue.internal.api.dto.clip2.helper.Setters; -import org.openhab.binding.hue.internal.api.serialization.InstantDeserializer; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; /** * JUnit test for sorting the sequence of scene events in a list. @@ -38,40 +34,39 @@ @NonNullByDefault class SortSceneResourcesTest { - private static final Gson GSON = new GsonBuilder().registerTypeAdapter(Instant.class, new InstantDeserializer()) - .create(); - - private static final String ACTIVE_SCENE_RESOURCE_ID = "ACTIVE00-0000-0000-0000-000000000001"; - - private String loadJson(String fileName) { - try (FileReader file = new FileReader(String.format("src/test/resources/%s.json", fileName)); - BufferedReader reader = new BufferedReader(file)) { - StringBuilder builder = new StringBuilder(); - String line; - while ((line = reader.readLine()) != null) { - builder.append(line).append("\n"); - } - return builder.toString(); - } catch (IOException e) { - fail(e.getMessage()); - } - return ""; - } + private static final JsonElement ACTIVE = JsonParser.parseString("{\"active\":\"static\"}"); + private static final JsonElement INACTIVE = JsonParser.parseString("{\"active\":\"inactive\"}"); @Test void testSceneSorting() { - Resources resources = GSON.fromJson(loadJson("scene_event"), Resources.class); - assertNotNull(resources); - List list = resources.getResources(); - assertNotNull(list); + List list = new ArrayList<>(); + list.add(new Resource(ResourceType.LIGHT).setId("0")); + list.add(new Resource(ResourceType.SCENE).setId("1").setStatus(ACTIVE)); + list.add(new Resource(ResourceType.LIGHT).setId("2")); + list.add(new Resource(ResourceType.SCENE).setId("3").setStatus(INACTIVE)); + list.add(new Resource(ResourceType.LIGHT).setId("4")); list.forEach(r -> r.markAsSparse()); assertEquals(5, list.size()); - assertEquals(ACTIVE_SCENE_RESOURCE_ID, list.get(1).getId()); + assertEquals("0", list.get(0).getId()); + assertEquals("1", list.get(1).getId()); + assertEquals("2", list.get(2).getId()); + assertEquals("3", list.get(3).getId()); + assertEquals("4", list.get(4).getId()); + + assertTrue(list.get(1).getSceneActive().get()); + assertFalse(list.get(3).getSceneActive().get()); Setters.sortSceneResources(list); assertEquals(5, list.size()); - assertEquals(ACTIVE_SCENE_RESOURCE_ID, list.get(4).getId()); + assertEquals("0", list.get(0).getId()); + assertEquals("2", list.get(1).getId()); + assertEquals("3", list.get(2).getId()); + assertEquals("4", list.get(3).getId()); + assertEquals("1", list.get(4).getId()); + + assertFalse(list.get(2).getSceneActive().get()); + assertTrue(list.get(4).getSceneActive().get()); } } diff --git a/bundles/org.openhab.binding.hue/src/test/resources/scene_event.json b/bundles/org.openhab.binding.hue/src/test/resources/scene_event.json deleted file mode 100644 index 598372fcab2c8..0000000000000 --- a/bundles/org.openhab.binding.hue/src/test/resources/scene_event.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "errors": [ - ], - "data": [ - { - "id": "00000000-0000-0000-0000-000000000000", - "id_v1": "/lights/40", - "on": { - "on": false - }, - "type": "light" - }, - { - "id": "ACTIVE00-0000-0000-0000-000000000001", - "id_v1": "/scenes/BK-UE-77VNFHKRi", - "status": { - "active": "static" - }, - "type": "scene" - }, - { - "id": "00000000-0000-0000-0000-000000000002", - "id_v1": "/lights/40", - "on": { - "on": false - }, - "type": "light" - }, - { - "id": "00000000-0000-0000-0000-000000000003", - "id_v1": "/scenes/rULmu6mjOgC4U7I", - "status": { - "active": "inactive" - }, - "type": "scene" - }, - { - "id": "00000000-0000-0000-0000-000000000004", - "id_v1": "/lights/40", - "on": { - "on": false - }, - "type": "light" - } - ] -}