From f38ef2643a9a14f714c1e69a6acbfa9b56598080 Mon Sep 17 00:00:00 2001 From: Christoph Weitkamp Date: Wed, 12 Feb 2020 18:19:06 +0100 Subject: [PATCH] [tradfri] Added basic support for IKEA blinds FYRTUR and KADRILJ (#6977) * Adds basic support for IKEA smart blinds FYRTUR and KADRILJ * adds the "blind" thing and associated data * temporarily assigned zigbee id "0999", needs review Signed-off-by: Manuel Raffel * Restores ISO 8859-1 encoding of .properties file Signed-off-by: Manuel Raffel * - Incorporated review comments - Added discovery - Added check for percent values - Aplied formatter - Fixed unit tests Signed-off-by: Christoph Weitkamp * Added repeater Signed-off-by: Christoph Weitkamp * Added TRADFRI open/close remote Signed-off-by: Christoph Weitkamp * Refactoring of discovery service Signed-off-by: Christoph Weitkamp * Added handling for STOP command Signed-off-by: Christoph Weitkamp * Incorporated changes from review Signed-off-by: Christoph Weitkamp Co-authored-by: Manuel --- bundles/org.openhab.binding.tradfri/README.md | 48 ++++--- bundles/org.openhab.binding.tradfri/pom.xml | 4 +- .../internal/DeviceUpdateListener.java | 2 + .../internal/TradfriBindingConstants.java | 34 ++++- .../tradfri/internal/TradfriColor.java | 5 +- .../internal/TradfriHandlerFactory.java | 55 +------- .../TradfriDiscoveryParticipant.java | 5 +- .../discovery/TradfriDiscoveryService.java | 52 ++++++-- .../internal/handler/TradfriBlindHandler.java | 123 ++++++++++++++++++ .../handler/TradfriControllerHandler.java | 14 +- .../handler/TradfriGatewayHandler.java | 13 +- .../handler/TradfriSensorHandler.java | 14 +- .../internal/model/TradfriBlindData.java | 66 ++++++++++ .../internal/model/TradfriDeviceData.java | 10 +- .../main/resources/ESH-INF/config/config.xml | 3 +- .../ESH-INF/i18n/tradfri_de.properties | 6 + .../resources/ESH-INF/thing/thing-types.xml | 44 +++++++ .../tradfri/internal/TradfriColorTest.java | 3 +- .../TradfriDiscoveryServiceTest.java | 46 ++++--- .../internal/model/TradfriVersionTest.java | 3 +- 20 files changed, 418 insertions(+), 132 deletions(-) create mode 100644 bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/handler/TradfriBlindHandler.java create mode 100644 bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/model/TradfriBlindData.java diff --git a/bundles/org.openhab.binding.tradfri/README.md b/bundles/org.openhab.binding.tradfri/README.md index 70a0b928f993d..e38b4a2f0dc4f 100644 --- a/bundles/org.openhab.binding.tradfri/README.md +++ b/bundles/org.openhab.binding.tradfri/README.md @@ -22,18 +22,22 @@ These are: | Non-Colour Controller | 0x0820 | 0820 | | Non-Colour Scene Controller | 0x0830 | 0830 | | Control Outlet | 0x0010 | 0010 | +| Window Covering Device | 0x0202 | 0202 | +| Window Covering Controller | 0x0202 | 0203 | The following matrix lists the capabilities (channels) for each of the supported lighting device types: -| Thing type | Brightness | Color | Color Temperature | Battery Level | Battery Low | Power | -|-------------|:----------:|:-----:|:-----------------:|:-------------:|:-----------:|:-----:| -| 0010 | | | | | | X | -| 0100 | X | | | | | | -| 0220 | X | | X | | | | -| 0210 | | X | X | | | | -| 0107 | | | | X | X | | -| 0820 | | | | X | X | | -| 0830 | | | | X | X | | +| Thing type | Brightness | Color | Color Temperature | Battery Level | Battery Low | Power | Position | +|-------------|:----------:|:-----:|:-----------------:|:-------------:|:-----------:|:-----:|:---------| +| 0010 | | | | | | X | | +| 0100 | X | | | | | | | +| 0220 | X | | X | | | | | +| 0210 | | X | X | | | | | +| 0107 | | | | X | X | | | +| 0820 | | | | X | X | | | +| 0830 | | | | X | X | | | +| 0202 | | | | X | X | | X | +| 0203 | | | | X | X | | | ## Thing Configuration @@ -59,16 +63,19 @@ The remote control and the motion sensor supports the `battery_level` and `batte The control outlet supports the `power` channel. +A blind or curtain supports beside `battery_level` and `battery_low` channels a `positon` channel. + Refer to the matrix above. -| Channel Type ID | Item Type | Description | -|-------------------|-----------|--------------------------------------------------| -| brightness | Dimmer | The brightness of the bulb in percent | -| color_temperature | Dimmer | color temperature from 0% = cold to 100% = warm | -| color | Color | full color | -| battery_level | Number | battery level (in %) | -| battery_low | Switch | battery low warning (<=10% = ON, >10% = OFF) | -| power | Switch | power switch | +| Channel Type ID | Item Type | Description | +|-------------------|---------------|--------------------------------------------------------| +| brightness | Dimmer | The brightness of the bulb in percent | +| color_temperature | Dimmer | color temperature from 0% = cold to 100% = warm | +| color | Color | full color | +| battery_level | Number | battery level (in %) | +| battery_low | Switch | battery low warning (<=10% = ON, >10% = OFF) | +| power | Switch | power switch | +| position | Rollershutter | position of the blinds from 0% = open to 100% = closed | ## Full Example @@ -81,6 +88,7 @@ Bridge tradfri:gateway:mygateway [ host="192.168.0.177", code="EHPW5rIJKyXFgjH3" 0210 myColorBulb "My Color Bulb" [ id=65539 ] 0830 myRemoteControl "My Remote Control" [ id=65545 ] 0010 myControlOutlet "My Control Outlet" [ id=65542 ] + 0202 myBlinds "My Blinds" [ id=65547 ] } ``` @@ -94,6 +102,7 @@ Color ColorLight { channel="tradfri:0210:mygateway:myColorBulb:color" } Number RemoteControlBatteryLevel { channel="tradfri:0830:mygateway:myRemoteControl:battery_level" } Switch RemoteControlBatteryLow { channel="tradfri:0830:mygateway:myRemoteControl:battery_low" } Switch ControlOutlet { channel="tradfri:0010:mygateway:myControlOutlet:power" } +Rollershutter BlindPosition { channel="tradfri:0202:mygateway:myBlinds:position" } ``` demo.sitemap: @@ -106,9 +115,10 @@ sitemap demo label="Main Menu" Slider item=Light2_Brightness label="Light2 Brightness [%.1f %%]" Slider item=Light2_ColorTemperature label="Light2 Color Temperature [%.1f %%]" Colorpicker item=ColorLight label="Color" - Text item=RemoteControlBatteryLevel label="Battery level [%d %%]" - Switch item=RemoteControlBatteryLow label="Battery low warning" + Text item=RemoteControlBatteryLevel label="Battery Level [%d %%]" + Switch item=RemoteControlBatteryLow label="Battery Low Warning" Switch item=ControlOutlet label="Power Switch" + Rollershutter item)BlindPosition label="Blind Position" } } ``` diff --git a/bundles/org.openhab.binding.tradfri/pom.xml b/bundles/org.openhab.binding.tradfri/pom.xml index 8b2dcfa84d116..0d833dfd2b7f7 100644 --- a/bundles/org.openhab.binding.tradfri/pom.xml +++ b/bundles/org.openhab.binding.tradfri/pom.xml @@ -1,4 +1,6 @@ - + + 4.0.0 diff --git a/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/DeviceUpdateListener.java b/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/DeviceUpdateListener.java index f90f7903be185..9e5e25a0028f0 100644 --- a/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/DeviceUpdateListener.java +++ b/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/DeviceUpdateListener.java @@ -12,6 +12,7 @@ */ package org.openhab.binding.tradfri.internal; +import org.eclipse.jdt.annotation.NonNullByDefault; import org.openhab.binding.tradfri.internal.handler.TradfriGatewayHandler; import com.google.gson.JsonObject; @@ -22,6 +23,7 @@ * * @author Kai Kreuzer - Initial contribution */ +@NonNullByDefault public interface DeviceUpdateListener { /** diff --git a/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/TradfriBindingConstants.java b/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/TradfriBindingConstants.java index a5776df916f57..4cb0a3098ec42 100644 --- a/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/TradfriBindingConstants.java +++ b/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/TradfriBindingConstants.java @@ -17,6 +17,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.smarthome.core.thing.ThingTypeUID; /** @@ -25,7 +26,9 @@ * * @author Kai Kreuzer - Initial contribution * @author Christoph Weitkamp - Added support for remote controller and motion sensor devices (read-only battery level) + * @author Manuel Raffel - Added support for blinds */ +@NonNullByDefault public class TradfriBindingConstants { private static final String BINDING_ID = "tradfri"; @@ -40,13 +43,16 @@ public class TradfriBindingConstants { public static final ThingTypeUID THING_TYPE_DIMMER = new ThingTypeUID(BINDING_ID, "0820"); public static final ThingTypeUID THING_TYPE_REMOTE_CONTROL = new ThingTypeUID(BINDING_ID, "0830"); public static final ThingTypeUID THING_TYPE_MOTION_SENSOR = new ThingTypeUID(BINDING_ID, "0107"); + public static final ThingTypeUID THING_TYPE_BLINDS = new ThingTypeUID(BINDING_ID, "0202"); + public static final ThingTypeUID THING_TYPE_OPEN_CLOSE_REMOTE_CONTROL = new ThingTypeUID(BINDING_ID, "0203"); public static final Set SUPPORTED_LIGHT_TYPES_UIDS = Collections .unmodifiableSet(Stream.of(THING_TYPE_DIMMABLE_LIGHT, THING_TYPE_COLOR_TEMP_LIGHT, THING_TYPE_COLOR_LIGHT) .collect(Collectors.toSet())); - public static final Set SUPPORTED_PLUG_TYPES_UIDS = Collections - .unmodifiableSet(Stream.of(THING_TYPE_ONOFF_PLUG).collect(Collectors.toSet())); + public static final Set SUPPORTED_PLUG_TYPES_UIDS = Collections.singleton(THING_TYPE_ONOFF_PLUG); + + public static final Set SUPPORTED_BLINDS_TYPES_UIDS = Collections.singleton(THING_TYPE_BLINDS); // List of all Gateway Configuration Properties public static final String GATEWAY_CONFIG_HOST = "host"; @@ -56,20 +62,34 @@ public class TradfriBindingConstants { public static final String GATEWAY_CONFIG_PRE_SHARED_KEY = "preSharedKey"; // Not yet used - included for future support - public static final Set SUPPORTED_CONTROLLER_TYPES_UIDS = Collections.unmodifiableSet(Stream - .of(THING_TYPE_DIMMER, THING_TYPE_REMOTE_CONTROL, THING_TYPE_MOTION_SENSOR).collect(Collectors.toSet())); + public static final Set SUPPORTED_CONTROLLER_TYPES_UIDS = Collections + .unmodifiableSet(Stream.of(THING_TYPE_DIMMER, THING_TYPE_REMOTE_CONTROL, + THING_TYPE_OPEN_CLOSE_REMOTE_CONTROL, THING_TYPE_MOTION_SENSOR).collect(Collectors.toSet())); + + public static final Set SUPPORTED_BRIDGE_TYPES_UIDS = Collections.singleton(GATEWAY_TYPE_UID); + + public static final Set SUPPORTED_DEVICE_TYPES_UIDS = Collections.unmodifiableSet(Stream + .of(SUPPORTED_LIGHT_TYPES_UIDS.stream(), SUPPORTED_CONTROLLER_TYPES_UIDS.stream(), + SUPPORTED_PLUG_TYPES_UIDS.stream(), SUPPORTED_BLINDS_TYPES_UIDS.stream()) + .reduce(Stream::concat).orElseGet(Stream::empty).collect(Collectors.toSet())); + + public static final Set SUPPORTED_THING_TYPES_UIDS = Collections + .unmodifiableSet(Stream.concat(SUPPORTED_BRIDGE_TYPES_UIDS.stream(), SUPPORTED_DEVICE_TYPES_UIDS.stream()) + .collect(Collectors.toSet())); // List of all Channel IDs public static final String CHANNEL_POWER = "power"; public static final String CHANNEL_BRIGHTNESS = "brightness"; public static final String CHANNEL_COLOR_TEMPERATURE = "color_temperature"; public static final String CHANNEL_COLOR = "color"; + public static final String CHANNEL_POSITION = "position"; public static final String CHANNEL_BATTERY_LEVEL = "battery_level"; public static final String CHANNEL_BATTERY_LOW = "battery_low"; // IPSO Objects public static final String DEVICES = "15001"; public static final String AUTH_PATH = "9063"; + public static final String BLINDS = "15015"; public static final String CLIENT_IDENTITY_PROPOSED = "9090"; public static final String COLOR = "5706"; public static final String COLOR_X = "5709"; @@ -135,9 +155,11 @@ public class TradfriBindingConstants { public static final String OTA_UPDATE_STATE = "9054"; public static final String PLUG = "3312"; public static final String POWER_FACTOR = "5820"; + public static final String POSITION = "5536"; public static final String REACHABILITY_STATE = "9019"; public static final String REBOOT = "9030"; public static final String REPEAT_DAYS = "9041"; + public static final String REPEATER = "15014"; public static final String RESET = "9031"; public static final String RESET_MIN_MAX_MSR = "5605"; public static final String SCENE = "15005"; @@ -158,6 +180,7 @@ public class TradfriBindingConstants { public static final String START_ACTION = "9042"; public static final String START_TIME_HR = "9046"; public static final String START_TIME_MN = "9047"; + public static final String STOP_TRIGGER = "5523"; public static final String SWITCH = "15009"; public static final String TIME_ARRAY = "9994"; public static final String TIME_REMAINING_IN_SECONDS = "9024"; @@ -172,9 +195,12 @@ public class TradfriBindingConstants { public static final int WAKE_UP_SMART_TASK = 3; public static final String TYPE_SWITCH = "0"; + public static final String TYPE_REMOTE = "1"; public static final String TYPE_LIGHT = "2"; public static final String TYPE_PLUG = "3"; public static final String TYPE_SENSOR = "4"; + public static final String TYPE_REPEATER = "6"; + public static final String TYPE_BLINDS = "7"; public static final String DEVICE_VENDOR = "0"; public static final String DEVICE_MODEL = "1"; public static final String DEVICE_FIRMWARE = "3"; diff --git a/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/TradfriColor.java b/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/TradfriColor.java index 4425353480bdc..9768c337af8f4 100644 --- a/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/TradfriColor.java +++ b/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/TradfriColor.java @@ -32,8 +32,8 @@ public class TradfriColor { // Tradfri uses the CIE color space (see https://en.wikipedia.org/wiki/CIE_1931_color_space), // which uses x,y-coordinates. // Its own app comes with 3 predefined color temperature settings (0,1,2), which have those values: - private final static double[] PRESET_X = new double[] { 24933.0, 30138.0, 33137.0 }; - private final static double[] PRESET_Y = new double[] { 24691.0, 26909.0, 27211.0 }; + private static final double[] PRESET_X = new double[] { 24933.0, 30138.0, 33137.0 }; + private static final double[] PRESET_Y = new double[] { 24691.0, 26909.0, 27211.0 }; /** * CIE XY color values in the tradfri range 0 to 65535. @@ -178,7 +178,6 @@ public PercentType getColorTemperature() { * @return {@link PercentType} with brightness level (0 = light is off, 1 = lowest, 100 = highest) */ public static PercentType xyBrightnessToPercentType(int xyBrightness) { - if (xyBrightness > 254) { return PercentType.HUNDRED; } else if (xyBrightness < 0) { diff --git a/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/TradfriHandlerFactory.java b/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/TradfriHandlerFactory.java index 1e2e72778faab..d35795d589823 100644 --- a/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/TradfriHandlerFactory.java +++ b/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/TradfriHandlerFactory.java @@ -14,30 +14,20 @@ import static org.openhab.binding.tradfri.internal.TradfriBindingConstants.*; -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.eclipse.smarthome.config.discovery.DiscoveryService; import org.eclipse.smarthome.core.thing.Bridge; import org.eclipse.smarthome.core.thing.Thing; import org.eclipse.smarthome.core.thing.ThingTypeUID; -import org.eclipse.smarthome.core.thing.ThingUID; import org.eclipse.smarthome.core.thing.binding.BaseThingHandlerFactory; import org.eclipse.smarthome.core.thing.binding.ThingHandler; import org.eclipse.smarthome.core.thing.binding.ThingHandlerFactory; -import org.openhab.binding.tradfri.internal.discovery.TradfriDiscoveryService; +import org.openhab.binding.tradfri.internal.handler.TradfriBlindHandler; import org.openhab.binding.tradfri.internal.handler.TradfriControllerHandler; import org.openhab.binding.tradfri.internal.handler.TradfriGatewayHandler; import org.openhab.binding.tradfri.internal.handler.TradfriLightHandler; import org.openhab.binding.tradfri.internal.handler.TradfriPlugHandler; import org.openhab.binding.tradfri.internal.handler.TradfriSensorHandler; -import org.osgi.framework.ServiceRegistration; import org.osgi.service.component.annotations.Component; /** @@ -45,18 +35,12 @@ * * @author Kai Kreuzer - Initial contribution * @author Christoph Weitkamp - Added support for remote controller and motion sensor devices (read-only battery level) + * @author Manuel Raffel - Added support for blinds */ @Component(service = ThingHandlerFactory.class, configurationPid = "binding.tradfri") @NonNullByDefault public class TradfriHandlerFactory extends BaseThingHandlerFactory { - private static final Set SUPPORTED_THING_TYPES_UIDS = Stream - .of(Stream.of(GATEWAY_TYPE_UID), SUPPORTED_LIGHT_TYPES_UIDS.stream(), - SUPPORTED_CONTROLLER_TYPES_UIDS.stream(), SUPPORTED_PLUG_TYPES_UIDS.stream()) - .reduce(Stream::concat).orElseGet(Stream::empty).collect(Collectors.toSet()); - - private final Map> discoveryServiceRegs = new HashMap<>(); - @Override public boolean supportsThingType(ThingTypeUID thingTypeUID) { return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID); @@ -67,13 +51,14 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) { ThingTypeUID thingTypeUID = thing.getThingTypeUID(); if (GATEWAY_TYPE_UID.equals(thingTypeUID)) { - TradfriGatewayHandler handler = new TradfriGatewayHandler((Bridge) thing); - registerDiscoveryService(handler); - return handler; - } else if (THING_TYPE_DIMMER.equals(thingTypeUID) || THING_TYPE_REMOTE_CONTROL.equals(thingTypeUID)) { + return new TradfriGatewayHandler((Bridge) thing); + } else if (THING_TYPE_DIMMER.equals(thingTypeUID) || THING_TYPE_REMOTE_CONTROL.equals(thingTypeUID) + || THING_TYPE_OPEN_CLOSE_REMOTE_CONTROL.equals(thingTypeUID)) { return new TradfriControllerHandler(thing); } else if (THING_TYPE_MOTION_SENSOR.equals(thingTypeUID)) { return new TradfriSensorHandler(thing); + } else if (THING_TYPE_BLINDS.equals(thingTypeUID)) { + return new TradfriBlindHandler(thing); } else if (SUPPORTED_LIGHT_TYPES_UIDS.contains(thingTypeUID)) { return new TradfriLightHandler(thing); } else if (SUPPORTED_PLUG_TYPES_UIDS.contains(thingTypeUID)) { @@ -82,30 +67,4 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) { return null; } - @Override - protected void removeHandler(ThingHandler thingHandler) { - if (thingHandler instanceof TradfriGatewayHandler) { - unregisterDiscoveryService((TradfriGatewayHandler) thingHandler); - } - } - - private synchronized void registerDiscoveryService(TradfriGatewayHandler bridgeHandler) { - TradfriDiscoveryService discoveryService = new TradfriDiscoveryService(bridgeHandler); - discoveryService.activate(); - this.discoveryServiceRegs.put(bridgeHandler.getThing().getUID(), getBundleContext() - .registerService(DiscoveryService.class.getName(), discoveryService, new Hashtable())); - } - - @SuppressWarnings("null") - private synchronized void unregisterDiscoveryService(TradfriGatewayHandler bridgeHandler) { - ServiceRegistration serviceReg = this.discoveryServiceRegs.remove(bridgeHandler.getThing().getUID()); - if (serviceReg != null) { - TradfriDiscoveryService service = (TradfriDiscoveryService) getBundleContext() - .getService(serviceReg.getReference()); - serviceReg.unregister(); - if (service != null) { - service.deactivate(); - } - } - } } diff --git a/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/discovery/TradfriDiscoveryParticipant.java b/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/discovery/TradfriDiscoveryParticipant.java index d4e6fe6d59366..11725f6777397 100644 --- a/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/discovery/TradfriDiscoveryParticipant.java +++ b/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/discovery/TradfriDiscoveryParticipant.java @@ -15,7 +15,6 @@ import static org.eclipse.smarthome.core.thing.Thing.*; import static org.openhab.binding.tradfri.internal.TradfriBindingConstants.*; -import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Set; @@ -54,11 +53,11 @@ public class TradfriDiscoveryParticipant implements MDNSDiscoveryParticipant { * gw:001122334455, gw-001122334455, gw:00-11-22-33-44-55, gw-001122334455ServiceName * */ - private final Pattern GATEWAY_NAME_REGEX_PATTERN = Pattern.compile("(gw[:-]{1}([a-f0-9]{2}[-]?){6}){1}"); + private static final Pattern GATEWAY_NAME_REGEX_PATTERN = Pattern.compile("(gw[:-]{1}([a-f0-9]{2}[-]?){6}){1}"); @Override public Set getSupportedThingTypeUIDs() { - return Collections.singleton(GATEWAY_TYPE_UID); + return SUPPORTED_BRIDGE_TYPES_UIDS; } @Override diff --git a/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/discovery/TradfriDiscoveryService.java b/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/discovery/TradfriDiscoveryService.java index 98279e6e48a9d..a299d11dfb04e 100644 --- a/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/discovery/TradfriDiscoveryService.java +++ b/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/discovery/TradfriDiscoveryService.java @@ -16,9 +16,11 @@ import static org.openhab.binding.tradfri.internal.TradfriBindingConstants.*; import java.util.Arrays; +import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -27,8 +29,11 @@ import org.eclipse.smarthome.config.discovery.AbstractDiscoveryService; import org.eclipse.smarthome.config.discovery.DiscoveryResult; import org.eclipse.smarthome.config.discovery.DiscoveryResultBuilder; +import org.eclipse.smarthome.config.discovery.DiscoveryService; import org.eclipse.smarthome.core.thing.ThingTypeUID; import org.eclipse.smarthome.core.thing.ThingUID; +import org.eclipse.smarthome.core.thing.binding.ThingHandler; +import org.eclipse.smarthome.core.thing.binding.ThingHandlerService; import org.openhab.binding.tradfri.internal.DeviceUpdateListener; import org.openhab.binding.tradfri.internal.handler.TradfriGatewayHandler; import org.slf4j.Logger; @@ -43,26 +48,28 @@ * @author Kai Kreuzer - Initial contribution * @author Christoph Weitkamp - Added support for remote controller and motion sensor devices (read-only battery level) * @author Andre Fuechsel - fixed the results removal + * @author Manuel Raffel - Added support for blinds */ @NonNullByDefault -public class TradfriDiscoveryService extends AbstractDiscoveryService implements DeviceUpdateListener { +public class TradfriDiscoveryService extends AbstractDiscoveryService + implements DeviceUpdateListener, DiscoveryService, ThingHandlerService { private final Logger logger = LoggerFactory.getLogger(TradfriDiscoveryService.class); - private final TradfriGatewayHandler handler; + private @Nullable TradfriGatewayHandler handler; private static final String REMOTE_CONTROLLER_MODEL = "TRADFRI remote control"; - private static final String[] COLOR_TEMP_MODELS = new String[] { "TRADFRI bulb E27 WS opal 980lm", - "TRADFRI bulb E27 WS clear 950lm", "TRADFRI bulb GU10 WS 400lm", "TRADFRI bulb E14 WS opal 400lm", - "FLOALT panel WS 30x30", "FLOALT panel WS 60x60", "FLOALT panel WS 30x90", - "TRADFRI bulb E12 WS opal 400lm" }; + private static final Set COLOR_TEMP_MODELS = Collections + .unmodifiableSet(Stream + .of("TRADFRI bulb E27 WS opal 980lm", "TRADFRI bulb E27 WS clear 950lm", + "TRADFRI bulb GU10 WS 400lm", "TRADFRI bulb E14 WS opal 400lm", "FLOALT panel WS 30x30", + "FLOALT panel WS 60x60", "FLOALT panel WS 30x90", "TRADFRI bulb E12 WS opal 400lm") + .collect(Collectors.toSet())); private static final String[] COLOR_MODEL_IDENTIFIER_HINTS = new String[] { "CWS", " C/WS " }; - public TradfriDiscoveryService(TradfriGatewayHandler bridgeHandler) { - super(Stream.concat(SUPPORTED_LIGHT_TYPES_UIDS.stream(), SUPPORTED_CONTROLLER_TYPES_UIDS.stream()) - .collect(Collectors.toSet()), 10, true); - this.handler = bridgeHandler; + public TradfriDiscoveryService() { + super(SUPPORTED_DEVICE_TYPES_UIDS, 10, true); } @Override @@ -76,6 +83,19 @@ protected synchronized void stopScan() { removeOlderResults(getTimestampOfLastScan()); } + @Override + public void setThingHandler(@Nullable ThingHandler handler) { + if (handler instanceof TradfriGatewayHandler) { + this.handler = (TradfriGatewayHandler) handler; + } + } + + @Override + public @Nullable ThingHandler getThingHandler() { + return handler; + } + + @Override public void activate() { handler.registerDeviceUpdateListener(this); } @@ -106,23 +126,25 @@ public void onUpdate(@Nullable String instanceId, @Nullable JsonObject data) { // concrete model names. // Color light: // As the protocol does not distinguishes between color and full-color lights, - // we check if the "CWS" identifier is given in the model name + // we check if the "CWS" or "CW/S" identifier is given in the model name ThingTypeUID thingType = null; if (model != null && Arrays.stream(COLOR_MODEL_IDENTIFIER_HINTS).anyMatch(model::contains)) { thingType = THING_TYPE_COLOR_LIGHT; } if (thingType == null && // - (state.has(COLOR) || (model != null && Arrays.asList(COLOR_TEMP_MODELS).contains(model)))) { + (state.has(COLOR) || (model != null && COLOR_TEMP_MODELS.contains(model)))) { thingType = THING_TYPE_COLOR_TEMP_LIGHT; } if (thingType == null) { thingType = THING_TYPE_DIMMABLE_LIGHT; } thingId = new ThingUID(thingType, bridge, Integer.toString(id)); + } else if (TYPE_BLINDS.equals(type) && data.has(BLINDS)) { + // Blinds + thingId = new ThingUID(THING_TYPE_BLINDS, bridge, Integer.toString(id)); } else if (TYPE_PLUG.equals(type) && data.has(PLUG)) { // Smart plug - ThingTypeUID thingType = THING_TYPE_ONOFF_PLUG; - thingId = new ThingUID(thingType, bridge, Integer.toString(id)); + thingId = new ThingUID(THING_TYPE_ONOFF_PLUG, bridge, Integer.toString(id)); } else if (TYPE_SWITCH.equals(type) && data.has(SWITCH)) { // Remote control and wireless dimmer // As protocol does not distinguishes between remote control and wireless dimmer, @@ -131,6 +153,8 @@ public void onUpdate(@Nullable String instanceId, @Nullable JsonObject data) { ? THING_TYPE_REMOTE_CONTROL : THING_TYPE_DIMMER; thingId = new ThingUID(thingType, bridge, Integer.toString(id)); + } else if (TYPE_REMOTE.equals(type)) { + thingId = new ThingUID(THING_TYPE_OPEN_CLOSE_REMOTE_CONTROL, bridge, Integer.toString(id)); } else if (TYPE_SENSOR.equals(type) && data.has(SENSOR)) { // Motion sensor thingId = new ThingUID(THING_TYPE_MOTION_SENSOR, bridge, Integer.toString(id)); diff --git a/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/handler/TradfriBlindHandler.java b/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/handler/TradfriBlindHandler.java new file mode 100644 index 0000000000000..a9dcb1e0369b8 --- /dev/null +++ b/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/handler/TradfriBlindHandler.java @@ -0,0 +1,123 @@ +/** + * Copyright (c) 2010-2020 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.tradfri.internal.handler; + +import static org.openhab.binding.tradfri.internal.TradfriBindingConstants.*; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.smarthome.core.library.types.DecimalType; +import org.eclipse.smarthome.core.library.types.OnOffType; +import org.eclipse.smarthome.core.library.types.PercentType; +import org.eclipse.smarthome.core.library.types.StopMoveType; +import org.eclipse.smarthome.core.library.types.UpDownType; +import org.eclipse.smarthome.core.thing.ChannelUID; +import org.eclipse.smarthome.core.thing.Thing; +import org.eclipse.smarthome.core.thing.ThingStatus; +import org.eclipse.smarthome.core.types.Command; +import org.eclipse.smarthome.core.types.RefreshType; +import org.openhab.binding.tradfri.internal.model.TradfriBlindData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.JsonElement; + +/** + * The {@link TradfriBlindHandler} is responsible for handling commands for individual blinds. + * + * @author Manuel Raffel - Initial contribution + */ +@NonNullByDefault +public class TradfriBlindHandler extends TradfriThingHandler { + + private final Logger logger = LoggerFactory.getLogger(TradfriBlindHandler.class); + + public TradfriBlindHandler(Thing thing) { + super(thing); + } + + @Override + public void onUpdate(JsonElement data) { + if (active && !(data.isJsonNull())) { + TradfriBlindData state = new TradfriBlindData(data); + updateStatus(state.getReachabilityStatus() ? ThingStatus.ONLINE : ThingStatus.OFFLINE); + + PercentType position = state.getPosition(); + if (position != null) { + updateState(CHANNEL_POSITION, position); + } + + DecimalType batteryLevel = state.getBatteryLevel(); + if (batteryLevel != null) { + updateState(CHANNEL_BATTERY_LEVEL, batteryLevel); + } + + OnOffType batteryLow = state.getBatteryLow(); + if (batteryLow != null) { + updateState(CHANNEL_BATTERY_LOW, batteryLow); + } + + updateDeviceProperties(state); + + logger.debug( + "Updating thing for blindId {} to state {position: {}, firmwareVersion: {}, modelId: {}, vendor: {}}", + state.getDeviceId(), position, state.getFirmwareVersion(), state.getModelId(), state.getVendor()); + } + } + + private void setPosition(PercentType percent) { + set(new TradfriBlindData().setPosition(percent).getJsonString()); + } + + private void triggerStop() { + set(new TradfriBlindData().stop().getJsonString()); + } + + @Override + public void handleCommand(ChannelUID channelUID, Command command) { + if (active) { + if (command instanceof RefreshType) { + logger.debug("Refreshing channel {}", channelUID); + coapClient.asyncGet(this); + return; + } + + switch (channelUID.getId()) { + case CHANNEL_POSITION: + handlePositionCommand(command); + break; + default: + logger.error("Unknown channel UID {}", channelUID); + } + } + } + + private void handlePositionCommand(Command command) { + if (command instanceof PercentType) { + setPosition((PercentType) command); + } else if (command instanceof StopMoveType) { + if (StopMoveType.STOP.equals(command)) { + triggerStop(); + } else { + logger.debug("Cannot handle command '{}' for channel '{}'", command, CHANNEL_POSITION); + } + } else if (command instanceof UpDownType) { + if (UpDownType.UP.equals(command)) { + setPosition(PercentType.ZERO); + } else { + setPosition(PercentType.HUNDRED); + } + } else { + logger.debug("Cannot handle command '{}' for channel '{}'", command, CHANNEL_POSITION); + } + } +} diff --git a/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/handler/TradfriControllerHandler.java b/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/handler/TradfriControllerHandler.java index a8d3fd8217bd7..3337f90c5f9b5 100644 --- a/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/handler/TradfriControllerHandler.java +++ b/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/handler/TradfriControllerHandler.java @@ -78,12 +78,14 @@ public void onUpdate(JsonElement data) { @Override public void handleCommand(ChannelUID channelUID, Command command) { - if (command instanceof RefreshType) { - logger.debug("Refreshing channel {}", channelUID); - coapClient.asyncGet(this); - return; - } + if (active) { + if (command instanceof RefreshType) { + logger.debug("Refreshing channel {}", channelUID); + coapClient.asyncGet(this); + return; + } - logger.debug("The controller is a read-only device and cannot handle commands."); + logger.debug("The controller is a read-only device and cannot handle commands."); + } } } diff --git a/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/handler/TradfriGatewayHandler.java b/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/handler/TradfriGatewayHandler.java index 86613cebb2859..b002bb7eb0014 100644 --- a/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/handler/TradfriGatewayHandler.java +++ b/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/handler/TradfriGatewayHandler.java @@ -18,6 +18,8 @@ import java.net.InetSocketAddress; import java.net.URI; import java.net.URISyntaxException; +import java.util.Collection; +import java.util.Collections; import java.util.Set; import java.util.UUID; import java.util.concurrent.CopyOnWriteArraySet; @@ -41,6 +43,7 @@ import org.eclipse.smarthome.core.thing.ThingStatusDetail; import org.eclipse.smarthome.core.thing.binding.BaseBridgeHandler; import org.eclipse.smarthome.core.thing.binding.ThingHandler; +import org.eclipse.smarthome.core.thing.binding.ThingHandlerService; import org.eclipse.smarthome.core.types.Command; import org.openhab.binding.tradfri.internal.CoapCallback; import org.openhab.binding.tradfri.internal.DeviceUpdateListener; @@ -48,6 +51,7 @@ import org.openhab.binding.tradfri.internal.TradfriCoapClient; import org.openhab.binding.tradfri.internal.TradfriCoapHandler; import org.openhab.binding.tradfri.internal.config.TradfriGatewayConfig; +import org.openhab.binding.tradfri.internal.discovery.TradfriDiscoveryService; import org.openhab.binding.tradfri.internal.model.TradfriVersion; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -131,6 +135,11 @@ public void initialize() { } } + @Override + public Collection> getServices() { + return Collections.singleton(TradfriDiscoveryService.class); + } + private void establishConnection() { TradfriGatewayConfig configuration = getConfigAs(TradfriGatewayConfig.class); @@ -243,8 +252,8 @@ protected boolean obtainIdentityAndPreSharedKey() { logger.warn("Invalid response received from gateway '{}'", responseText, e); updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, String.format("Invalid response received from gateway '%s'", responseText)); - } catch (ConnectorException |IOException e) { - logger.debug("Error connecting to gateway ",e); + } catch (ConnectorException | IOException e) { + logger.debug("Error connecting to gateway ", e); updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, String.format("Error connecting to gateway.")); } diff --git a/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/handler/TradfriSensorHandler.java b/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/handler/TradfriSensorHandler.java index c40d0ddd1f45e..0c06264824b5f 100644 --- a/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/handler/TradfriSensorHandler.java +++ b/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/handler/TradfriSensorHandler.java @@ -69,12 +69,14 @@ public void onUpdate(JsonElement data) { @Override public void handleCommand(ChannelUID channelUID, Command command) { - if (command instanceof RefreshType) { - logger.debug("Refreshing channel {}", channelUID); - coapClient.asyncGet(this); - return; - } + if (active) { + if (command instanceof RefreshType) { + logger.debug("Refreshing channel {}", channelUID); + coapClient.asyncGet(this); + return; + } - logger.debug("The sensor is a read-only device and cannot handle commands."); + logger.debug("The sensor is a read-only device and cannot handle commands."); + } } } diff --git a/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/model/TradfriBlindData.java b/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/model/TradfriBlindData.java new file mode 100644 index 0000000000000..aaa295d2f69e2 --- /dev/null +++ b/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/model/TradfriBlindData.java @@ -0,0 +1,66 @@ +/** + * Copyright (c) 2010-2020 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.tradfri.internal.model; + +import static org.openhab.binding.tradfri.internal.TradfriBindingConstants.*; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.smarthome.core.library.types.PercentType; + +import com.google.gson.JsonElement; +import com.google.gson.JsonPrimitive; + +/** + * The {@link TradfriBlindData} class is a Java wrapper for the raw JSON data about the blinds state. + * + * @author Manuel Raffel - Initial contribution + */ +@NonNullByDefault +public class TradfriBlindData extends TradfriWirelessDeviceData { + public TradfriBlindData() { + super(BLINDS); + } + + public TradfriBlindData(JsonElement json) { + super(BLINDS, json); + } + + public TradfriBlindData setPosition(PercentType position) { + attributes.add(POSITION, new JsonPrimitive(position.intValue())); + return this; + } + + public TradfriBlindData stop() { + attributes.add(STOP_TRIGGER, new JsonPrimitive(0)); + return this; + } + + public @Nullable PercentType getPosition() { + PercentType result = null; + + JsonElement position = attributes.get(POSITION); + if (position != null) { + int percent = position.getAsInt(); + percent = Math.max(percent, 0); + percent = Math.min(100, percent); + result = new PercentType(percent); + } + + return result; + } + + public String getJsonString() { + return root.toString(); + } +} diff --git a/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/model/TradfriDeviceData.java b/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/model/TradfriDeviceData.java index ec860c316d0d6..3ab6a0cf426bc 100644 --- a/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/model/TradfriDeviceData.java +++ b/bundles/org.openhab.binding.tradfri/src/main/java/org/openhab/binding/tradfri/internal/model/TradfriDeviceData.java @@ -53,8 +53,14 @@ public TradfriDeviceData(String attributesNodeName) { public TradfriDeviceData(String attributesNodeName, JsonElement json) { try { root = json.getAsJsonObject(); - array = root.getAsJsonArray(attributesNodeName); - attributes = array.get(0).getAsJsonObject(); + if (root.has(attributesNodeName)) { + array = root.getAsJsonArray(attributesNodeName); + attributes = array.get(0).getAsJsonObject(); + } else { + array = new JsonArray(); + attributes = new JsonObject(); + array.add(attributes); + } generalInfo = root.getAsJsonObject(DEVICE); } catch (JsonSyntaxException e) { logger.warn("JSON error: {}", e.getMessage(), e); diff --git a/bundles/org.openhab.binding.tradfri/src/main/resources/ESH-INF/config/config.xml b/bundles/org.openhab.binding.tradfri/src/main/resources/ESH-INF/config/config.xml index 51cc802dafecf..bd2d76ecc5da2 100644 --- a/bundles/org.openhab.binding.tradfri/src/main/resources/ESH-INF/config/config.xml +++ b/bundles/org.openhab.binding.tradfri/src/main/resources/ESH-INF/config/config.xml @@ -1,5 +1,6 @@ - diff --git a/bundles/org.openhab.binding.tradfri/src/main/resources/ESH-INF/i18n/tradfri_de.properties b/bundles/org.openhab.binding.tradfri/src/main/resources/ESH-INF/i18n/tradfri_de.properties index 8ca9164336346..9793ad0cb60cd 100644 --- a/bundles/org.openhab.binding.tradfri/src/main/resources/ESH-INF/i18n/tradfri_de.properties +++ b/bundles/org.openhab.binding.tradfri/src/main/resources/ESH-INF/i18n/tradfri_de.properties @@ -27,6 +27,10 @@ thing-type.tradfri.0820.label = Kabelloser Dimmer thing-type.tradfri.0820.description = Der Kabellose Dimmer liefert Daten wie z.B. die Batterieladung. thing-type.tradfri.0830.label = Fernbedienung thing-type.tradfri.0830.description = Die Fernbedienung liefert Daten wie z.B. die Batterieladung. +thing-type.tradfri.0202.label = Rollo +thing-type.tradfri.0202.description = Batteriebetriebenes Rollo mit einstellbarer Position. Liefert außerdem Daten wie z.B. die Batterieladung. +thing-type.tradfri.0203.label = Rollo-Fernbedienung +thing-type.tradfri.0203.description = Die Rollo-Fernbedienung liefert Daten wie z.B. die Batterieladung. # thing types config thing-type.config.tradfri.device.id.label = ID des Gerätes @@ -39,3 +43,5 @@ channel-type.tradfri.color_temperature.label = Farbtemperatur channel-type.tradfri.color_temperature.description = Ermöglicht die Steuerung der Farbtemperatur. Von Tageslichtweiß (0) bis Warmweiß (100). channel-type.tradfri.color.label = Farbe channel-type.tradfri.color.description = Ermöglicht die Steuerung der Farbe. +channel-type.tradfri.position.label = Position +channel-type.tradfri.position.description = Ermöglicht die Steuerung der Position von Offen (0) bis Geschlossen (100). diff --git a/bundles/org.openhab.binding.tradfri/src/main/resources/ESH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.tradfri/src/main/resources/ESH-INF/thing/thing-types.xml index f3676a93cd564..e1c7fbd311892 100644 --- a/bundles/org.openhab.binding.tradfri/src/main/resources/ESH-INF/thing/thing-types.xml +++ b/bundles/org.openhab.binding.tradfri/src/main/resources/ESH-INF/thing/thing-types.xml @@ -137,6 +137,43 @@ + + + + + + + This represents a blind or curtain that can be moved up and down. Also reports current battery level. + + + + + + + + id + + + + + + + + + + + This represents the wireless open/close remote capable of reporting the battery level. + + + + + + + id + + + + Dimmer @@ -147,6 +184,13 @@ + + Rollershutter + + Control the position of the blind or curtain in percent from 0 (open) to 100 (closed). + Blinds + + Dimmer diff --git a/bundles/org.openhab.binding.tradfri/src/test/java/org/openhab/binding/tradfri/internal/TradfriColorTest.java b/bundles/org.openhab.binding.tradfri/src/test/java/org/openhab/binding/tradfri/internal/TradfriColorTest.java index cb5dd02426d2a..1f37eaf694770 100644 --- a/bundles/org.openhab.binding.tradfri/src/test/java/org/openhab/binding/tradfri/internal/TradfriColorTest.java +++ b/bundles/org.openhab.binding.tradfri/src/test/java/org/openhab/binding/tradfri/internal/TradfriColorTest.java @@ -14,16 +14,17 @@ import static org.junit.Assert.*; +import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.smarthome.core.library.types.HSBType; import org.eclipse.smarthome.core.library.types.PercentType; import org.junit.Test; -import org.openhab.binding.tradfri.internal.TradfriColor; /** * Tests for {@link TradfriColor}. * * @author Holger Reichert - Initial contribution */ +@NonNullByDefault public class TradfriColorTest { @Test diff --git a/bundles/org.openhab.binding.tradfri/src/test/java/org/openhab/binding/tradfri/internal/discovery/TradfriDiscoveryServiceTest.java b/bundles/org.openhab.binding.tradfri/src/test/java/org/openhab/binding/tradfri/internal/discovery/TradfriDiscoveryServiceTest.java index 237caba3abc71..9f96e02a59e02 100644 --- a/bundles/org.openhab.binding.tradfri/src/test/java/org/openhab/binding/tradfri/internal/discovery/TradfriDiscoveryServiceTest.java +++ b/bundles/org.openhab.binding.tradfri/src/test/java/org/openhab/binding/tradfri/internal/discovery/TradfriDiscoveryServiceTest.java @@ -32,7 +32,6 @@ import org.junit.Before; import org.junit.Test; import org.mockito.Mock; -import org.openhab.binding.tradfri.internal.discovery.TradfriDiscoveryService; import org.openhab.binding.tradfri.internal.handler.TradfriGatewayHandler; import com.google.gson.JsonObject; @@ -51,7 +50,23 @@ public class TradfriDiscoveryServiceTest { @Mock private TradfriGatewayHandler handler; - private DiscoveryListener listener; + private final DiscoveryListener listener = new DiscoveryListener() { + @Override + public void thingRemoved(DiscoveryService source, ThingUID thingUID) { + } + + @Override + public void thingDiscovered(DiscoveryService source, DiscoveryResult result) { + discoveryResult = result; + } + + @Override + public Collection removeOlderResults(DiscoveryService source, long timestamp, + Collection thingTypeUIDs, ThingUID bridgeUID) { + return null; + } + }; + private DiscoveryResult discoveryResult; private TradfriDiscoveryService discovery; @@ -59,25 +74,11 @@ public class TradfriDiscoveryServiceTest { @Before public void setUp() { initMocks(this); + when(handler.getThing()).thenReturn(BridgeBuilder.create(GATEWAY_TYPE_UID, "1").build()); - discovery = new TradfriDiscoveryService(handler); - - listener = new DiscoveryListener() { - @Override - public void thingRemoved(DiscoveryService source, ThingUID thingUID) { - } - - @Override - public void thingDiscovered(DiscoveryService source, DiscoveryResult result) { - discoveryResult = result; - } - - @Override - public Collection removeOlderResults(DiscoveryService source, long timestamp, - Collection thingTypeUIDs, ThingUID bridgeUID) { - return null; - } - }; + + discovery = new TradfriDiscoveryService(); + discovery.setThingHandler(handler); discovery.addDiscoveryListener(listener); } @@ -88,13 +89,16 @@ public void cleanUp() { @Test public void correctSupportedTypes() { - assertThat(discovery.getSupportedThingTypes().size(), is(6)); + assertThat(discovery.getSupportedThingTypes().size(), is(9)); assertTrue(discovery.getSupportedThingTypes().contains(THING_TYPE_DIMMABLE_LIGHT)); assertTrue(discovery.getSupportedThingTypes().contains(THING_TYPE_COLOR_TEMP_LIGHT)); assertTrue(discovery.getSupportedThingTypes().contains(THING_TYPE_COLOR_LIGHT)); assertTrue(discovery.getSupportedThingTypes().contains(THING_TYPE_DIMMER)); assertTrue(discovery.getSupportedThingTypes().contains(THING_TYPE_MOTION_SENSOR)); assertTrue(discovery.getSupportedThingTypes().contains(THING_TYPE_REMOTE_CONTROL)); + assertTrue(discovery.getSupportedThingTypes().contains(THING_TYPE_OPEN_CLOSE_REMOTE_CONTROL)); + assertTrue(discovery.getSupportedThingTypes().contains(THING_TYPE_ONOFF_PLUG)); + assertTrue(discovery.getSupportedThingTypes().contains(THING_TYPE_BLINDS)); } @Test diff --git a/bundles/org.openhab.binding.tradfri/src/test/java/org/openhab/binding/tradfri/internal/model/TradfriVersionTest.java b/bundles/org.openhab.binding.tradfri/src/test/java/org/openhab/binding/tradfri/internal/model/TradfriVersionTest.java index cc0a2175eb730..bc76b29e06fe3 100644 --- a/bundles/org.openhab.binding.tradfri/src/test/java/org/openhab/binding/tradfri/internal/model/TradfriVersionTest.java +++ b/bundles/org.openhab.binding.tradfri/src/test/java/org/openhab/binding/tradfri/internal/model/TradfriVersionTest.java @@ -16,14 +16,15 @@ import java.util.Arrays; +import org.eclipse.jdt.annotation.NonNullByDefault; import org.junit.Test; -import org.openhab.binding.tradfri.internal.model.TradfriVersion; /** * Tests for {@link TradfriVersion}. * * @author Christoph Weitkamp - Initial contribution */ +@NonNullByDefault public class TradfriVersionTest { private static final int LESS_THAN = -1;