From 25826854b4ff83537de9bcb73b68d0abc73ff8bf Mon Sep 17 00:00:00 2001 From: Christoph Weitkamp Date: Fri, 16 Oct 2020 00:51:41 +0200 Subject: [PATCH] [hue] Refactored discovery service to 'ThingHandlerService' (#8729) * Refactored discovery service to ThingHandlerService * Fixed discovery for Geofence Sensor Signed-off-by: Christoph Weitkamp --- .../binding/hue/internal/FullHueObject.java | 8 +- .../binding/hue/internal/FullLight.java | 8 +- .../binding/hue/internal/FullSensor.java | 12 +- .../hue/internal/HueThingHandlerFactory.java | 35 +---- ...ce.java => HueDeviceDiscoveryService.java} | 135 +++++++++++------- .../internal/handler/HueBridgeHandler.java | 40 +++--- .../hue/internal/handler/HueClient.java | 8 +- ...=> HueDeviceDiscoveryServiceOSGiTest.java} | 15 +- 8 files changed, 136 insertions(+), 125 deletions(-) rename bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/discovery/{HueLightDiscoveryService.java => HueDeviceDiscoveryService.java} (69%) rename itests/org.openhab.binding.hue.tests/src/main/java/org/openhab/binding/hue/internal/{HueLightDiscoveryServiceOSGiTest.java => HueDeviceDiscoveryServiceOSGiTest.java} (94%) diff --git a/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/FullHueObject.java b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/FullHueObject.java index 2f5e07711..a5fb4f1ae 100644 --- a/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/FullHueObject.java +++ b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/FullHueObject.java @@ -108,8 +108,14 @@ public class FullHueObject extends HueObject { * * @return the unique id, can be null for some virtual types like the daylight sensor */ - public @Nullable String getUniqueID() { return uniqueid; } + + /** + * Sets the unique id of the object. + */ + protected void setUniqueID(final String uniqueid) { + this.uniqueid = uniqueid; + } } diff --git a/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/FullLight.java b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/FullLight.java index d0a48e633..f3a1d83a6 100644 --- a/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/FullLight.java +++ b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/FullLight.java @@ -16,6 +16,8 @@ import java.lang.reflect.Type; import java.time.Duration; import java.util.Map; +import org.eclipse.jdt.annotation.NonNullByDefault; + import com.google.gson.reflect.TypeToken; /** @@ -26,16 +28,14 @@ import com.google.gson.reflect.TypeToken; * @author Denis Dudnik - moved Jue library source code inside the smarthome Hue binding * @author Samuel Leisering - added GSon Type to FullLight, refactored content to {@link FullHueObject} */ +@NonNullByDefault public class FullLight extends FullHueObject { public static final Type GSON_TYPE = new TypeToken>() { }.getType(); - private State state; + private @NonNullByDefault({}) State state; private final long fadetime = 400; // milliseconds - FullLight() { - } - /** * Returns the current state of the light. * diff --git a/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/FullSensor.java b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/FullSensor.java index 800e47d45..497dc2c64 100644 --- a/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/FullSensor.java +++ b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/FullSensor.java @@ -15,6 +15,8 @@ package org.openhab.binding.hue.internal; import java.lang.reflect.Type; import java.util.Map; +import org.eclipse.jdt.annotation.NonNullByDefault; + import com.google.gson.reflect.TypeToken; /** @@ -23,7 +25,10 @@ import com.google.gson.reflect.TypeToken; * @author Samuel Leisering - Initial contribution * @author Christoph Weitkamp - Initial contribution */ +@NonNullByDefault public class FullSensor extends FullHueObject { + public static final Type GSON_TYPE = new TypeToken>() { + }.getType(); public static final String STATE_LAST_UPDATED = "lastupdated"; public static final String STATE_BUTTON_EVENT = "buttonevent"; @@ -46,11 +51,8 @@ public class FullSensor extends FullHueObject { public static final String CONFIG_LIGHT_LEVEL_THRESHOLD_DARK = "tholddark"; public static final String CONFIG_LIGHT_LEVEL_THRESHOLD_OFFSET = "tholdoffset"; - public static final Type GSON_TYPE = new TypeToken>() { - }.getType(); - - private Map state; - private Map config; + private @NonNullByDefault({}) Map state; + private @NonNullByDefault({}) Map config; public Map getState() { return state; diff --git a/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/HueThingHandlerFactory.java b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/HueThingHandlerFactory.java index 21fdc431e..5724bb2c2 100644 --- a/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/HueThingHandlerFactory.java +++ b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/HueThingHandlerFactory.java @@ -15,16 +15,12 @@ package org.openhab.binding.hue.internal; import static org.openhab.binding.hue.internal.HueBindingConstants.*; import java.util.Collections; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; -import org.openhab.binding.hue.internal.discovery.HueLightDiscoveryService; import org.openhab.binding.hue.internal.handler.HueBridgeHandler; import org.openhab.binding.hue.internal.handler.HueGroupHandler; import org.openhab.binding.hue.internal.handler.HueLightHandler; @@ -37,7 +33,6 @@ import org.openhab.binding.hue.internal.handler.sensors.PresenceHandler; import org.openhab.binding.hue.internal.handler.sensors.TapSwitchHandler; import org.openhab.binding.hue.internal.handler.sensors.TemperatureHandler; import org.openhab.core.config.core.Configuration; -import org.openhab.core.config.discovery.DiscoveryService; import org.openhab.core.thing.Bridge; import org.openhab.core.thing.Thing; import org.openhab.core.thing.ThingTypeUID; @@ -45,7 +40,6 @@ import org.openhab.core.thing.ThingUID; import org.openhab.core.thing.binding.BaseThingHandlerFactory; import org.openhab.core.thing.binding.ThingHandler; import org.openhab.core.thing.binding.ThingHandlerFactory; -import org.osgi.framework.ServiceRegistration; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Reference; @@ -75,8 +69,6 @@ public class HueThingHandlerFactory extends BaseThingHandlerFactory { private final HueStateDescriptionOptionProvider stateOptionProvider; - private final Map> discoveryServiceRegs = new HashMap<>(); - @Activate public HueThingHandlerFactory(final @Reference HueStateDescriptionOptionProvider stateOptionProvider) { this.stateOptionProvider = stateOptionProvider; @@ -150,9 +142,7 @@ public class HueThingHandlerFactory extends BaseThingHandlerFactory { @Override protected @Nullable ThingHandler createHandler(Thing thing) { if (HueBridgeHandler.SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())) { - HueBridgeHandler handler = new HueBridgeHandler((Bridge) thing, stateOptionProvider); - registerLightDiscoveryService(handler); - return handler; + return new HueBridgeHandler((Bridge) thing, stateOptionProvider); } else if (HueLightHandler.SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())) { return new HueLightHandler(thing); } else if (DimmerSwitchHandler.SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())) { @@ -175,27 +165,4 @@ public class HueThingHandlerFactory extends BaseThingHandlerFactory { return null; } } - - private synchronized void registerLightDiscoveryService(HueBridgeHandler bridgeHandler) { - HueLightDiscoveryService discoveryService = new HueLightDiscoveryService(bridgeHandler); - discoveryService.activate(); - this.discoveryServiceRegs.put(bridgeHandler.getThing().getUID(), - bundleContext.registerService(DiscoveryService.class.getName(), discoveryService, new Hashtable<>())); - } - - @Override - protected synchronized void removeHandler(ThingHandler thingHandler) { - if (thingHandler instanceof HueBridgeHandler) { - ServiceRegistration serviceReg = this.discoveryServiceRegs.remove(thingHandler.getThing().getUID()); - if (serviceReg != null) { - // remove discovery service, if bridge handler is removed - HueLightDiscoveryService service = (HueLightDiscoveryService) bundleContext - .getService(serviceReg.getReference()); - serviceReg.unregister(); - if (service != null) { - service.deactivate(); - } - } - } - } } diff --git a/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/discovery/HueLightDiscoveryService.java b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/discovery/HueDeviceDiscoveryService.java similarity index 69% rename from bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/discovery/HueLightDiscoveryService.java rename to bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/discovery/HueDeviceDiscoveryService.java index 7d301df4c..c77c9286a 100644 --- a/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/discovery/HueLightDiscoveryService.java +++ b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/discovery/HueDeviceDiscoveryService.java @@ -43,9 +43,12 @@ import org.openhab.binding.hue.internal.handler.sensors.TemperatureHandler; import org.openhab.core.config.discovery.AbstractDiscoveryService; import org.openhab.core.config.discovery.DiscoveryResult; import org.openhab.core.config.discovery.DiscoveryResultBuilder; +import org.openhab.core.config.discovery.DiscoveryService; import org.openhab.core.thing.Thing; import org.openhab.core.thing.ThingTypeUID; import org.openhab.core.thing.ThingUID; +import org.openhab.core.thing.binding.ThingHandler; +import org.openhab.core.thing.binding.ThingHandlerService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -64,7 +67,9 @@ import org.slf4j.LoggerFactory; * @author Laurent Garnier - Added support for groups */ @NonNullByDefault -public class HueLightDiscoveryService extends AbstractDiscoveryService { +public class HueDeviceDiscoveryService extends AbstractDiscoveryService + implements DiscoveryService, ThingHandlerService { + public static final Set SUPPORTED_THING_TYPES = Collections.unmodifiableSet(Stream .of(HueLightHandler.SUPPORTED_THING_TYPES.stream(), DimmerSwitchHandler.SUPPORTED_THING_TYPES.stream(), TapSwitchHandler.SUPPORTED_THING_TYPES.stream(), PresenceHandler.SUPPORTED_THING_TYPES.stream(), @@ -73,12 +78,8 @@ public class HueLightDiscoveryService extends AbstractDiscoveryService { ClipHandler.SUPPORTED_THING_TYPES.stream(), HueGroupHandler.SUPPORTED_THING_TYPES.stream()) .flatMap(i -> i).collect(Collectors.toSet())); - private final Logger logger = LoggerFactory.getLogger(HueLightDiscoveryService.class); - - private static final int SEARCH_TIME = 10; - // @formatter:off - private static final Map TYPE_TO_ZIGBEE_ID_MAP = Stream.of( + private static final Map TYPE_TO_ZIGBEE_ID_MAP = Map.ofEntries( new SimpleEntry<>("on_off_light", "0000"), new SimpleEntry<>("on_off_plug_in_unit", "0010"), new SimpleEntry<>("dimmable_light", "0100"), @@ -91,27 +92,50 @@ public class HueLightDiscoveryService extends AbstractDiscoveryService { new SimpleEntry<>("clipgenericstatus", "0840"), new SimpleEntry<>("clipgenericflag", "0850"), new SimpleEntry<>("zllpresence", "0107"), - new SimpleEntry<>("geofence", "0107"), + new SimpleEntry<>("geofence", "geofencesensor"), new SimpleEntry<>("zlltemperature", "0302"), - new SimpleEntry<>("zlllightlevel", "0106") - ).collect(Collectors.toMap((e) -> e.getKey(), (e) -> e.getValue())); + new SimpleEntry<>("zlllightlevel", "0106")); // @formatter:on - private final HueBridgeHandler hueBridgeHandler; + private static final int SEARCH_TIME = 10; - public HueLightDiscoveryService(HueBridgeHandler hueBridgeHandler) { - super(SEARCH_TIME); - this.hueBridgeHandler = hueBridgeHandler; + private final Logger logger = LoggerFactory.getLogger(HueDeviceDiscoveryService.class); + + private @Nullable HueBridgeHandler hueBridgeHandler; + private @Nullable ThingUID bridgeUID; + + public HueDeviceDiscoveryService() { + super(SUPPORTED_THING_TYPES, SEARCH_TIME); } + @Override + public void setThingHandler(@Nullable ThingHandler handler) { + if (handler instanceof HueBridgeHandler) { + hueBridgeHandler = (HueBridgeHandler) handler; + bridgeUID = handler.getThing().getUID(); + } + } + + @Override + public @Nullable ThingHandler getThingHandler() { + return hueBridgeHandler; + } + + @Override public void activate() { - hueBridgeHandler.registerDiscoveryListener(this); + final HueBridgeHandler handler = hueBridgeHandler; + if (handler != null) { + handler.registerDiscoveryListener(this); + } } @Override public void deactivate() { - removeOlderResults(new Date().getTime(), hueBridgeHandler.getThing().getUID()); - hueBridgeHandler.unregisterDiscoveryListener(); + removeOlderResults(new Date().getTime(), bridgeUID); + final HueBridgeHandler handler = hueBridgeHandler; + if (handler != null) { + handler.unregisterDiscoveryListener(); + } } @Override @@ -121,26 +145,32 @@ public class HueLightDiscoveryService extends AbstractDiscoveryService { @Override public void startScan() { - List lights = hueBridgeHandler.getFullLights(); - for (FullLight l : lights) { - addLightDiscovery(l); + final HueBridgeHandler handler = hueBridgeHandler; + if (handler != null) { + List lights = handler.getFullLights(); + for (FullLight l : lights) { + addLightDiscovery(l); + } + List sensors = handler.getFullSensors(); + for (FullSensor s : sensors) { + addSensorDiscovery(s); + } + List groups = handler.getFullGroups(); + for (FullGroup g : groups) { + addGroupDiscovery(g); + } + // search for unpaired lights + handler.startSearch(); } - List sensors = hueBridgeHandler.getFullSensors(); - for (FullSensor s : sensors) { - addSensorDiscovery(s); - } - List groups = hueBridgeHandler.getFullGroups(); - for (FullGroup g : groups) { - addGroupDiscovery(g); - } - // search for unpaired lights - hueBridgeHandler.startSearch(); } @Override protected synchronized void stopScan() { super.stopScan(); - removeOlderResults(getTimestampOfLastScan(), hueBridgeHandler.getThing().getUID()); + final HueBridgeHandler handler = hueBridgeHandler; + if (handler != null) { + removeOlderResults(getTimestampOfLastScan(), handler.getThing().getUID()); + } } public void addLightDiscovery(FullLight light) { @@ -150,7 +180,6 @@ public class HueLightDiscoveryService extends AbstractDiscoveryService { String modelId = light.getNormalizedModelID(); if (thingUID != null && thingTypeUID != null) { - ThingUID bridgeUID = hueBridgeHandler.getThing().getUID(); Map properties = new HashMap<>(); properties.put(LIGHT_ID, light.getId()); if (modelId != null) { @@ -181,14 +210,15 @@ public class HueLightDiscoveryService extends AbstractDiscoveryService { } private @Nullable ThingUID getThingUID(FullHueObject hueObject) { - ThingUID bridgeUID = hueBridgeHandler.getThing().getUID(); - ThingTypeUID thingTypeUID = getThingTypeUID(hueObject); + ThingUID localBridgeUID = bridgeUID; + if (localBridgeUID != null) { + ThingTypeUID thingTypeUID = getThingTypeUID(hueObject); - if (thingTypeUID != null && getSupportedThingTypes().contains(thingTypeUID)) { - return new ThingUID(thingTypeUID, bridgeUID, hueObject.getId()); - } else { - return null; + if (thingTypeUID != null && getSupportedThingTypes().contains(thingTypeUID)) { + return new ThingUID(thingTypeUID, localBridgeUID, hueObject.getId()); + } } + return null; } private @Nullable ThingTypeUID getThingTypeUID(FullHueObject hueObject) { @@ -203,7 +233,6 @@ public class HueLightDiscoveryService extends AbstractDiscoveryService { String modelId = sensor.getNormalizedModelID(); if (thingUID != null && thingTypeUID != null) { - ThingUID bridgeUID = hueBridgeHandler.getThing().getUID(); Map properties = new HashMap<>(); properties.put(SENSOR_ID, sensor.getId()); if (modelId != null) { @@ -239,24 +268,28 @@ public class HueLightDiscoveryService extends AbstractDiscoveryService { return; } - ThingUID bridgeUID = hueBridgeHandler.getThing().getUID(); - ThingUID thingUID = new ThingUID(THING_TYPE_GROUP, bridgeUID, group.getId()); + ThingUID localBridgeUID = bridgeUID; + if (localBridgeUID != null) { + ThingUID thingUID = new ThingUID(THING_TYPE_GROUP, localBridgeUID, group.getId()); - Map properties = new HashMap<>(); - properties.put(GROUP_ID, group.getId()); + Map properties = new HashMap<>(); + properties.put(GROUP_ID, group.getId()); - String name = String.format("%s (%s)", "0".equals(group.getId()) ? "All lights" : group.getName(), - group.getType()); - DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID).withThingType(THING_TYPE_GROUP) - .withProperties(properties).withBridge(bridgeUID).withRepresentationProperty(GROUP_ID).withLabel(name) - .build(); + String name = String.format("%s (%s)", "0".equals(group.getId()) ? "All lights" : group.getName(), + group.getType()); + DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID).withThingType(THING_TYPE_GROUP) + .withProperties(properties).withBridge(localBridgeUID).withRepresentationProperty(GROUP_ID) + .withLabel(name).build(); - thingDiscovered(discoveryResult); + thingDiscovered(discoveryResult); + } } public void removeGroupDiscovery(FullGroup group) { - ThingUID bridgeUID = hueBridgeHandler.getThing().getUID(); - ThingUID thingUID = new ThingUID(THING_TYPE_GROUP, bridgeUID, group.getId()); - thingRemoved(thingUID); + ThingUID localBridgeUID = bridgeUID; + if (localBridgeUID != null) { + ThingUID thingUID = new ThingUID(THING_TYPE_GROUP, localBridgeUID, group.getId()); + thingRemoved(thingUID); + } } } diff --git a/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/handler/HueBridgeHandler.java b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/handler/HueBridgeHandler.java index d08b89218..163ceae23 100644 --- a/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/handler/HueBridgeHandler.java +++ b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/handler/HueBridgeHandler.java @@ -46,7 +46,7 @@ import org.openhab.binding.hue.internal.Scene; import org.openhab.binding.hue.internal.State; import org.openhab.binding.hue.internal.StateUpdate; import org.openhab.binding.hue.internal.config.HueBridgeConfig; -import org.openhab.binding.hue.internal.discovery.HueLightDiscoveryService; +import org.openhab.binding.hue.internal.discovery.HueDeviceDiscoveryService; import org.openhab.binding.hue.internal.exceptions.ApiException; import org.openhab.binding.hue.internal.exceptions.DeviceOffException; import org.openhab.binding.hue.internal.exceptions.EntityNotAvailableException; @@ -63,6 +63,7 @@ import org.openhab.core.thing.ThingStatus; import org.openhab.core.thing.ThingStatusDetail; import org.openhab.core.thing.ThingTypeUID; import org.openhab.core.thing.binding.ConfigStatusBridgeHandler; +import org.openhab.core.thing.binding.ThingHandlerService; import org.openhab.core.types.Command; import org.openhab.core.types.StateOption; import org.slf4j.Logger; @@ -87,7 +88,7 @@ import org.slf4j.LoggerFactory; @NonNullByDefault public class HueBridgeHandler extends ConfigStatusBridgeHandler implements HueClient { - public static final Set SUPPORTED_THING_TYPES = Collections.singleton(THING_TYPE_BRIDGE); + public static final Set SUPPORTED_THING_TYPES = Set.of(THING_TYPE_BRIDGE); private static final long BYPASS_MIN_DURATION_BEFORE_CMD = 1500L; @@ -102,7 +103,7 @@ public class HueBridgeHandler extends ConfigStatusBridgeHandler implements HueCl private final Map lastSensorStates = new ConcurrentHashMap<>(); private final Map lastGroupStates = new ConcurrentHashMap<>(); - private @Nullable HueLightDiscoveryService discoveryService; + private @Nullable HueDeviceDiscoveryService discoveryService; private final Map lightStatusListeners = new ConcurrentHashMap<>(); private final Map sensorStatusListeners = new ConcurrentHashMap<>(); private final Map groupStatusListeners = new ConcurrentHashMap<>(); @@ -183,7 +184,7 @@ public class HueBridgeHandler extends ConfigStatusBridgeHandler implements HueCl protected void doConnectedRun() throws IOException, ApiException { Map lastSensorStateCopy = new HashMap<>(lastSensorStates); - final HueLightDiscoveryService discovery = discoveryService; + final HueDeviceDiscoveryService discovery = discoveryService; for (final FullSensor sensor : hueBridge.getSensors()) { String sensorId = sensor.getId(); @@ -239,7 +240,7 @@ public class HueBridgeHandler extends ConfigStatusBridgeHandler implements HueCl lights = hueBridge.getFullConfig().getLights(); } - final HueLightDiscoveryService discovery = discoveryService; + final HueDeviceDiscoveryService discovery = discoveryService; for (final FullLight fullLight : lights) { final String lightId = fullLight.getId(); @@ -282,7 +283,7 @@ public class HueBridgeHandler extends ConfigStatusBridgeHandler implements HueCl List groups = hueBridge.getGroups(); - final HueLightDiscoveryService discovery = discoveryService; + final HueDeviceDiscoveryService discovery = discoveryService; for (final FullGroup fullGroup : groups) { State groupState = new State(); @@ -409,6 +410,11 @@ public class HueBridgeHandler extends ConfigStatusBridgeHandler implements HueCl this.stateDescriptionOptionProvider = stateDescriptionOptionProvider; } + @Override + public Collection> getServices() { + return Collections.singleton(HueDeviceDiscoveryService.class); + } + @Override public void handleCommand(ChannelUID channelUID, Command command) { if (CHANNEL_SCENE.equals(channelUID.getId()) && command instanceof StringType) { @@ -528,7 +534,7 @@ public class HueBridgeHandler extends ConfigStatusBridgeHandler implements HueCl } } else if (e instanceof EntityNotAvailableException) { logger.debug("Error while accessing light: {}", e.getMessage(), e); - final HueLightDiscoveryService discovery = discoveryService; + final HueDeviceDiscoveryService discovery = discoveryService; if (discovery != null) { discovery.removeLightDiscovery(light); } @@ -541,7 +547,7 @@ public class HueBridgeHandler extends ConfigStatusBridgeHandler implements HueCl private void handleSensorUpdateException(FullSensor sensor, Throwable e) { if (e instanceof EntityNotAvailableException) { logger.debug("Error while accessing sensor: {}", e.getMessage(), e); - final HueLightDiscoveryService discovery = discoveryService; + final HueDeviceDiscoveryService discovery = discoveryService; if (discovery != null) { discovery.removeSensorDiscovery(sensor); } @@ -557,7 +563,7 @@ public class HueBridgeHandler extends ConfigStatusBridgeHandler implements HueCl private void handleGroupUpdateException(FullGroup group, Throwable e) { if (e instanceof EntityNotAvailableException) { logger.debug("Error while accessing group: {}", e.getMessage(), e); - final HueLightDiscoveryService discovery = discoveryService; + final HueDeviceDiscoveryService discovery = discoveryService; if (discovery != null) { discovery.removeGroupDiscovery(group); } @@ -840,7 +846,7 @@ public class HueBridgeHandler extends ConfigStatusBridgeHandler implements HueCl } @Override - public boolean registerDiscoveryListener(HueLightDiscoveryService listener) { + public boolean registerDiscoveryListener(HueDeviceDiscoveryService listener) { if (discoveryService == null) { discoveryService = listener; getFullLights().forEach(listener::addLightDiscovery); @@ -964,21 +970,21 @@ public class HueBridgeHandler extends ConfigStatusBridgeHandler implements HueCl List ret = withReAuthentication("search for new lights", () -> { return hueBridge.getFullLights(); }); - return ret != null ? ret : Collections.emptyList(); + return ret != null ? ret : List.of(); } public List getFullSensors() { List ret = withReAuthentication("search for new sensors", () -> { return hueBridge.getSensors(); }); - return ret != null ? ret : Collections.emptyList(); + return ret != null ? ret : List.of(); } public List getFullGroups() { List ret = withReAuthentication("search for new groups", () -> { return hueBridge.getGroups(); }); - return ret != null ? ret : Collections.emptyList(); + return ret != null ? ret : List.of(); } public void startSearch() { @@ -1024,17 +1030,13 @@ public class HueBridgeHandler extends ConfigStatusBridgeHandler implements HueCl @Override public Collection getConfigStatus() { // The bridge IP address to be used for checks - Collection configStatusMessages; - // Check whether an IP address is provided String ip = hueBridgeConfig.getIpAddress(); if (ip == null || ip.isEmpty()) { - configStatusMessages = Collections.singletonList(ConfigStatusMessage.Builder.error(HOST) + return List.of(ConfigStatusMessage.Builder.error(HOST) .withMessageKeySuffix(HueConfigStatusMessage.IP_ADDRESS_MISSING).withArguments(HOST).build()); } else { - configStatusMessages = Collections.emptyList(); + return List.of(); } - - return configStatusMessages; } } diff --git a/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/handler/HueClient.java b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/handler/HueClient.java index 92463d1bf..94115d5d8 100644 --- a/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/handler/HueClient.java +++ b/bundles/org.openhab.binding.hue/src/main/java/org/openhab/binding/hue/internal/handler/HueClient.java @@ -19,7 +19,7 @@ import org.openhab.binding.hue.internal.FullGroup; import org.openhab.binding.hue.internal.FullLight; import org.openhab.binding.hue.internal.FullSensor; import org.openhab.binding.hue.internal.StateUpdate; -import org.openhab.binding.hue.internal.discovery.HueLightDiscoveryService; +import org.openhab.binding.hue.internal.discovery.HueDeviceDiscoveryService; /** * Access to the Hue system for light handlers. @@ -33,15 +33,15 @@ import org.openhab.binding.hue.internal.discovery.HueLightDiscoveryService; public interface HueClient { /** - * Register {@link HueLightDiscoveryService} to bridge handler + * Register {@link HueDeviceDiscoveryService} to bridge handler * * @param listener the discovery service * @return {@code true} if the new discovery service is accepted */ - boolean registerDiscoveryListener(HueLightDiscoveryService listener); + boolean registerDiscoveryListener(HueDeviceDiscoveryService listener); /** - * Unregister {@link HueLightDiscoveryService} from bridge handler + * Unregister {@link HueDeviceDiscoveryService} from bridge handler * * @return {@code true} if the discovery service was removed */ diff --git a/itests/org.openhab.binding.hue.tests/src/main/java/org/openhab/binding/hue/internal/HueLightDiscoveryServiceOSGiTest.java b/itests/org.openhab.binding.hue.tests/src/main/java/org/openhab/binding/hue/internal/HueDeviceDiscoveryServiceOSGiTest.java similarity index 94% rename from itests/org.openhab.binding.hue.tests/src/main/java/org/openhab/binding/hue/internal/HueLightDiscoveryServiceOSGiTest.java rename to itests/org.openhab.binding.hue.tests/src/main/java/org/openhab/binding/hue/internal/HueDeviceDiscoveryServiceOSGiTest.java index 4f12f297b..c7a8ab08a 100644 --- a/itests/org.openhab.binding.hue.tests/src/main/java/org/openhab/binding/hue/internal/HueLightDiscoveryServiceOSGiTest.java +++ b/itests/org.openhab.binding.hue.tests/src/main/java/org/openhab/binding/hue/internal/HueDeviceDiscoveryServiceOSGiTest.java @@ -27,7 +27,7 @@ import java.util.concurrent.atomic.AtomicReference; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.openhab.binding.hue.internal.discovery.HueLightDiscoveryService; +import org.openhab.binding.hue.internal.discovery.HueDeviceDiscoveryService; import org.openhab.binding.hue.internal.handler.HueBridgeHandler; import org.openhab.core.config.core.Configuration; import org.openhab.core.config.discovery.DiscoveryListener; @@ -44,7 +44,7 @@ import org.openhab.core.thing.ThingUID; import org.openhab.core.thing.binding.builder.ThingStatusInfoBuilder; /** - * Tests for {@link HueLightDiscoveryService}. + * Tests for {@link HueDeviceDiscoveryService}. * * @author Kai Kreuzer - Initial contribution * @author Andre Fuechsel - added test 'assert start search is called()' @@ -52,14 +52,14 @@ import org.openhab.core.thing.binding.builder.ThingStatusInfoBuilder; * @author Denis Dudnik - switched to internally integrated source of Jue library * @author Markus Rathgeb - migrated to plain Java test */ -public class HueLightDiscoveryServiceOSGiTest extends AbstractHueOSGiTestParent { +public class HueDeviceDiscoveryServiceOSGiTest extends AbstractHueOSGiTestParent { protected HueThingHandlerFactory hueThingHandlerFactory; protected DiscoveryListener discoveryListener; protected ThingRegistry thingRegistry; protected Bridge hueBridge; protected HueBridgeHandler hueBridgeHandler; - protected HueLightDiscoveryService discoveryService; + protected HueDeviceDiscoveryService discoveryService; protected final ThingTypeUID BRIDGE_THING_TYPE_UID = new ThingTypeUID("hue", "bridge"); protected final ThingUID BRIDGE_THING_UID = new ThingUID(BRIDGE_THING_TYPE_UID, "testBridge"); @@ -85,7 +85,7 @@ public class HueLightDiscoveryServiceOSGiTest extends AbstractHueOSGiTestParent hueBridgeHandler = getThingHandler(hueBridge, HueBridgeHandler.class); assertThat(hueBridgeHandler, is(notNullValue())); - discoveryService = getService(DiscoveryService.class, HueLightDiscoveryService.class); + discoveryService = getService(DiscoveryService.class, HueDeviceDiscoveryService.class); assertThat(discoveryService, is(notNullValue())); } @@ -93,7 +93,7 @@ public class HueLightDiscoveryServiceOSGiTest extends AbstractHueOSGiTestParent public void cleanUp() { thingRegistry.remove(BRIDGE_THING_UID); waitForAssert(() -> { - assertNull(getService(DiscoveryService.class, HueLightDiscoveryService.class)); + assertNull(getService(DiscoveryService.class, HueDeviceDiscoveryService.class)); }); } @@ -113,6 +113,7 @@ public class HueLightDiscoveryServiceOSGiTest extends AbstractHueOSGiTestParent public void hueLightRegistration() { FullLight light = new FullLight(); light.setId("1"); + light.setUniqueID("AA:BB:CC:DD:EE:FF:00:11-XX"); light.setModelID("LCT001"); light.setType("Extended color light"); @@ -164,7 +165,7 @@ public class HueLightDiscoveryServiceOSGiTest extends AbstractHueOSGiTestParent if (address.endsWith("testUserName")) { String body = "{\"lights\":{}}"; return new Result(body, 200); - } else if (address.endsWith("lights") || address.endsWith("sensors")) { + } else if (address.endsWith("lights") || address.endsWith("sensors") || address.endsWith("groups")) { String body = "{}"; return new Result(body, 200); } else if (address.endsWith("testUserName/config")) {