]> git.basschouten.com Git - openhab-addons.git/commitdiff
[avmfritz] Added support for HAN-FUN blinds (#10492)
authorquidam <quidam@users.noreply.github.com>
Thu, 15 Apr 2021 15:50:11 +0000 (17:50 +0200)
committerGitHub <noreply@github.com>
Thu, 15 Apr 2021 15:50:11 +0000 (17:50 +0200)
* Added support for HAN-FUN blinds

Closes #10430

Signed-off-by: Ulrich Mertin <mail@ulrich-mertin.de>
15 files changed:
bundles/org.openhab.binding.avmfritz/README.md
bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/AVMFritzBindingConstants.java
bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/dto/AVMFritzBaseModel.java
bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/dto/DeviceModel.java
bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/dto/LevelcontrolModel.java [new file with mode: 0644]
bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/handler/AVMFritzBaseBridgeHandler.java
bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/handler/AVMFritzBaseThingHandler.java
bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/hardware/FritzAhaWebInterface.java
bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/hardware/callbacks/FritzAhaSetBlindLevelCallback.java [new file with mode: 0644]
bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/hardware/callbacks/FritzAhaSetBlindTargetCallback.java [new file with mode: 0644]
bundles/org.openhab.binding.avmfritz/src/main/resources/OH-INF/i18n/avmfritz_de.properties
bundles/org.openhab.binding.avmfritz/src/main/resources/OH-INF/thing/channel-types.xml
bundles/org.openhab.binding.avmfritz/src/main/resources/OH-INF/thing/thing-types.xml
bundles/org.openhab.binding.avmfritz/src/test/java/org/openhab/binding/avmfritz/internal/dto/AVMFritzDeviceListModelTest.java
itests/org.openhab.binding.avmfritz.tests/src/main/java/org/openhab/binding/avmfritz/internal/discovery/AVMFritzDiscoveryServiceOSGiTest.java

index 68dda54997f587a9cb0c41b8c660cf650e75c831..d5f7df539eda1c42ffd5c8a8e97248f3542a81ca 100644 (file)
@@ -84,6 +84,7 @@ The following sensors have been successfully tested using FRITZ!OS 7 for FRITZ!B
 - [SmartHome Bewegungsmelder](https://www.smarthome.de/geraete/telekom-smarthome-bewegungsmelder-innen) - a motion sensor (thing type `HAN_FUN_CONTACT`)
 - [SmartHome Rauchmelder](https://www.smarthome.de/geraete/smarthome-rauchmelder-weiss) - a smoke detector (thing type `HAN_FUN_CONTACT`)
 - [SmartHome Wandtaster](https://www.smarthome.de/geraete/telekom-smarthome-wandtaster) - a switch with two buttons (thing type `HAN_FUN_SWITCH`)
+- [Rollershutter/Blinds](https://www.rademacher.de/shop/rollladen-sonnenschutz/elektrischer-gurtwickler/rollotron-dect-1213) - an electronic belt winder (thing type `HAN_FUN_BLINDS`)
 
 The use of other Sensors should be possible, if these are compatible with DECT-ULE / HAN-FUN standards.
 
@@ -185,6 +186,7 @@ The AIN (actor identification number) can be found in the FRITZ!Box interface ->
 | battery_low     | Switch                   | Battery level low (ON/OFF) - FRITZ!OS 6.80                                                                                                         | FRITZ!DECT 301, FRITZ!DECT 300, Comet DECT, FRITZ!DECT 400, FRITZ!DECT 440                                          |
 | contact_state   | Contact                  | Contact state information (OPEN/CLOSED).                                                                                                           | HAN-FUN contact (e.g. SmartHome Tür-/Fensterkontakt or SmartHome Bewegungsmelder)- FRITZ!OS 7                       |
 | last_change     | DateTime                 | States the last time the button was pressed.                                                                                                       | FRITZ!DECT 400, FRITZ!DECT 440, HAN-FUN switch (e.g. SmartHome Wandtaster) - FRITZ!OS 7                             |
+| rollershutter   | Rollershutter            | Rollershutter control and status. Accepts UP/DOWN/STOP commands and the opening level in percent. States the opening level in percent.                                                                                                        | HAN-FUN blind (e.g. Rolltron DECT 1213) - FRITZ!OS 7                             |
 
 ### Triggers
 
index 05b60fc34c3bed2a9c8e557abb35bd3101470f02..792e7e466573eef24bc9ddf73a036864f22df866 100644 (file)
@@ -28,6 +28,7 @@ import org.openhab.core.thing.ThingTypeUID;
  * @author Christoph Weitkamp - Added support for AVM FRITZ!DECT 300 and Comet DECT
  * @author Christoph Weitkamp - Added support for groups
  * @author Christoph Weitkamp - Added channels 'voltage' and 'battery_level'
+ * @author Ulrich Mertin - Added support for HAN-FUN blinds
  */
 @NonNullByDefault
 public class AVMFritzBindingConstants {
@@ -52,6 +53,7 @@ public class AVMFritzBindingConstants {
     public static final String DEVICE_COMETDECT = "Comet_DECT";
     public static final String DEVICE_HAN_FUN_CONTACT = "HAN_FUN_CONTACT";
     public static final String DEVICE_HAN_FUN_SWITCH = "HAN_FUN_SWITCH";
+    public static final String DEVICE_HAN_FUN_BLINDS = "HAN_FUN_BLINDS";
 
     // List of main group types
     public static final String GROUP_HEATING = "FRITZ_GROUP_HEATING";
@@ -72,6 +74,7 @@ public class AVMFritzBindingConstants {
     public static final ThingTypeUID COMETDECT_THING_TYPE = new ThingTypeUID(BINDING_ID, DEVICE_COMETDECT);
     public static final ThingTypeUID HAN_FUN_CONTACT_THING_TYPE = new ThingTypeUID(BINDING_ID, DEVICE_HAN_FUN_CONTACT);
     public static final ThingTypeUID HAN_FUN_SWITCH_THING_TYPE = new ThingTypeUID(BINDING_ID, DEVICE_HAN_FUN_SWITCH);
+    public static final ThingTypeUID HAN_FUN_BLINDS_THING_TYPE = new ThingTypeUID(BINDING_ID, DEVICE_HAN_FUN_BLINDS);
     public static final ThingTypeUID GROUP_HEATING_THING_TYPE = new ThingTypeUID(BINDING_ID, GROUP_HEATING);
     public static final ThingTypeUID GROUP_SWITCH_THING_TYPE = new ThingTypeUID(BINDING_ID, GROUP_SWITCH);
 
@@ -125,6 +128,7 @@ public class AVMFritzBindingConstants {
     public static final String CHANNEL_CONTACT_STATE = "contact_state";
     public static final String CHANNEL_PRESS = "press";
     public static final String CHANNEL_LAST_CHANGE = "last_change";
+    public static final String CHANNEL_ROLLERSHUTTER = "rollershutter";
 
     // List of all Channel config ids
     public static final String CONFIG_CHANNEL_TEMP_OFFSET = "offset";
@@ -164,7 +168,8 @@ public class AVMFritzBindingConstants {
             COMETDECT_THING_TYPE);
 
     public static final Set<ThingTypeUID> SUPPORTED_DEVICE_THING_TYPES_UIDS = Set.of(DECT100_THING_TYPE,
-            DECT200_THING_TYPE, DECT210_THING_TYPE, PL546E_THING_TYPE, HAN_FUN_CONTACT_THING_TYPE);
+            DECT200_THING_TYPE, DECT210_THING_TYPE, PL546E_THING_TYPE, HAN_FUN_CONTACT_THING_TYPE,
+            HAN_FUN_BLINDS_THING_TYPE);
 
     public static final Set<ThingTypeUID> SUPPORTED_GROUP_THING_TYPES_UIDS = Set.of(GROUP_HEATING_THING_TYPE,
             GROUP_SWITCH_THING_TYPE);
index d13e96dbc65971de2e38eb657ec70d4d70df8d76..60e38a1b205dddd27455f8a4f62d023d59e8ac62 100644 (file)
@@ -39,6 +39,7 @@ import javax.xml.bind.annotation.XmlElement;
  * @author Robert Bausdorf - Initial contribution
  * @author Christoph Weitkamp - Added support for AVM FRITZ!DECT 300 and Comet DECT
  * @author Christoph Weitkamp - Added support for groups
+ * @author Ulrich Mertin - Added support for HAN-FUN blinds
  */
 public abstract class AVMFritzBaseModel implements BatteryModel {
     protected static final int HAN_FUN_DEVICE_BIT = 1; // Bit 0
@@ -52,6 +53,7 @@ public abstract class AVMFritzBaseModel implements BatteryModel {
     protected static final int DECT_REPEATER_BIT = 1 << 10; // Bit 10
     protected static final int MICROPHONE_BIT = 1 << 11; // Bit 11
     protected static final int HAN_FUN_UNIT_BIT = 1 << 13; // Bit 13
+    protected static final int HAN_FUN_BLINDS_BIT = 1 << 18; // Bit 18
     protected static final int HUMIDITY_SENSOR_BIT = 1 << 20; // Bit 20 - undocumented
 
     @XmlAttribute(name = "identifier")
@@ -177,6 +179,10 @@ public abstract class AVMFritzBaseModel implements BatteryModel {
         return (bitmask & HAN_FUN_UNIT_BIT) > 0;
     }
 
+    public boolean isHANFUNBlinds() {
+        return (bitmask & HAN_FUN_BLINDS_BIT) > 0;
+    }
+
     public String getFirmwareVersion() {
         return firmwareVersion;
     }
@@ -216,11 +222,12 @@ public abstract class AVMFritzBaseModel implements BatteryModel {
                 .append(isTempSensor()).append(",isHumiditySensor=").append(isHumiditySensor()).append(",isPowermeter=")
                 .append(isPowermeter()).append(",isDectRepeater=").append(isDectRepeater())
                 .append(",isHeatingThermostat=").append(isHeatingThermostat()).append(",isMicrophone=")
-                .append(isMicrophone()).append(",isHANFUNUnit=").append(isHANFUNUnit()).append(",id=").append(deviceId)
-                .append(",manufacturer=").append(deviceManufacturer).append(",productname=").append(productName)
-                .append(",fwversion=").append(firmwareVersion).append(",present=").append(present).append(",name=")
-                .append(name).append(",battery=").append(getBattery()).append(",batterylow=").append(getBatterylow())
-                .append(",").append(getSwitch()).append(",").append(getPowermeter()).append(",").append(getHkr())
-                .append(",").toString();
+                .append(isMicrophone()).append(",isHANFUNUnit=").append(isHANFUNUnit()).append(",isHANFUNBlind=")
+                .append(isHANFUNBlinds()).append(",id=").append(deviceId).append(",manufacturer=")
+                .append(deviceManufacturer).append(",productname=").append(productName).append(",fwversion=")
+                .append(firmwareVersion).append(",present=").append(present).append(",name=").append(name)
+                .append(",battery=").append(getBattery()).append(",batterylow=").append(getBatterylow()).append(",")
+                .append(getSwitch()).append(",").append(getPowermeter()).append(",").append(getHkr()).append(",")
+                .toString();
     }
 }
index 9fbb401eb2788452b456c4f5e331ccdd35342118..9bfe1bda0e13cc3708bf57673d05914681c1f551 100644 (file)
@@ -24,6 +24,7 @@ import javax.xml.bind.annotation.XmlType;
  *
  * @author Robert Bausdorf - Initial contribution
  * @author Christoph Weitkamp - Added support for groups
+ * @author Ulrich Mertin - Added support for HAN-FUN blinds
  */
 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name = "device")
@@ -32,6 +33,7 @@ public class DeviceModel extends AVMFritzBaseModel {
     private TemperatureModel temperature;
     private HumidityModel humidity;
     private AlertModel alert;
+    private LevelcontrolModel levelcontrol;
 
     @XmlElement(name = "button", type = ButtonModel.class)
     private List<ButtonModel> buttons;
@@ -62,6 +64,14 @@ public class DeviceModel extends AVMFritzBaseModel {
         this.alert = alertModel;
     }
 
+    public LevelcontrolModel getLevelcontrol() {
+        return levelcontrol;
+    }
+
+    public void setLevelcontrol(LevelcontrolModel levelcontrol) {
+        this.levelcontrol = levelcontrol;
+    }
+
     public List<ButtonModel> getButtons() {
         return buttons == null ? List.of() : buttons;
     }
diff --git a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/dto/LevelcontrolModel.java b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/dto/LevelcontrolModel.java
new file mode 100644 (file)
index 0000000..2d2198f
--- /dev/null
@@ -0,0 +1,58 @@
+/**
+ * Copyright (c) 2010-2021 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.avmfritz.internal.dto;
+
+import java.math.BigDecimal;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * See {@link DeviceListModel}.
+ *
+ * @author Ulrich Mertin - Initial contribution
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlRootElement(name = "levelcontrol")
+public class LevelcontrolModel {
+
+    @XmlElement(name = "level")
+    private BigDecimal level;
+
+    @XmlElement(name = "levelpercentage")
+    private BigDecimal levelPercentage;
+
+    public BigDecimal getLevel() {
+        return level != null ? level : BigDecimal.ZERO;
+    }
+
+    public void setLevel(BigDecimal level) {
+        this.level = level;
+    }
+
+    public BigDecimal getLevelPercentage() {
+        return levelPercentage != null ? levelPercentage : BigDecimal.ZERO;
+    }
+
+    public void setLevelPercentage(BigDecimal levelPercentage) {
+        this.levelPercentage = levelPercentage;
+    }
+
+    @Override
+    public String toString() {
+        return new StringBuilder().append("[level=").append(getLevel()).append(",levelpercentage=")
+                .append(getLevelPercentage()).append("]").toString();
+    }
+}
index 0c63ddfe307859223b6148a2c3bcdc6552eddfc6..62b3c5180142faa30b9f2de89ecb641b26e88c19 100644 (file)
@@ -64,6 +64,7 @@ import org.slf4j.LoggerFactory;
  * @author Robert Bausdorf - Initial contribution
  * @author Christoph Weitkamp - Added support for AVM FRITZ!DECT 300 and Comet DECT
  * @author Christoph Weitkamp - Added support for groups
+ * @author Ulrich Mertin - Added support for HAN-FUN blinds
  */
 @NonNullByDefault
 public abstract class AVMFritzBaseBridgeHandler extends BaseBridgeHandler {
@@ -326,6 +327,9 @@ public abstract class AVMFritzBaseBridgeHandler extends BaseBridgeHandler {
                 return GROUP_SWITCH;
             }
         } else if (device instanceof DeviceModel && device.isHANFUNUnit()) {
+            if (device.isHANFUNBlinds()) {
+                return DEVICE_HAN_FUN_BLINDS;
+            }
             List<String> interfaces = Arrays
                     .asList(((DeviceModel) device).getEtsiunitinfo().getInterfaces().split(","));
             if (interfaces.contains(HAN_FUN_INTERFACE_ALERT)) {
index aed952d2442f5213fef7c74a1c9f57094863bd88..b6759a1c454ee40f25e74cc45ff0618d7b1a5f67 100644 (file)
@@ -33,19 +33,24 @@ import org.openhab.binding.avmfritz.internal.dto.DeviceModel;
 import org.openhab.binding.avmfritz.internal.dto.HeatingModel;
 import org.openhab.binding.avmfritz.internal.dto.HeatingModel.NextChangeModel;
 import org.openhab.binding.avmfritz.internal.dto.HumidityModel;
+import org.openhab.binding.avmfritz.internal.dto.LevelcontrolModel;
 import org.openhab.binding.avmfritz.internal.dto.PowerMeterModel;
 import org.openhab.binding.avmfritz.internal.dto.SwitchModel;
 import org.openhab.binding.avmfritz.internal.dto.TemperatureModel;
 import org.openhab.binding.avmfritz.internal.hardware.FritzAhaStatusListener;
 import org.openhab.binding.avmfritz.internal.hardware.FritzAhaWebInterface;
+import org.openhab.binding.avmfritz.internal.hardware.callbacks.FritzAhaSetBlindTargetCallback.BlindCommand;
 import org.openhab.core.config.core.Configuration;
 import org.openhab.core.library.types.DateTimeType;
 import org.openhab.core.library.types.DecimalType;
 import org.openhab.core.library.types.IncreaseDecreaseType;
 import org.openhab.core.library.types.OnOffType;
 import org.openhab.core.library.types.OpenClosedType;
+import org.openhab.core.library.types.PercentType;
 import org.openhab.core.library.types.QuantityType;
+import org.openhab.core.library.types.StopMoveType;
 import org.openhab.core.library.types.StringType;
+import org.openhab.core.library.types.UpDownType;
 import org.openhab.core.library.unit.SIUnits;
 import org.openhab.core.library.unit.Units;
 import org.openhab.core.thing.Bridge;
@@ -73,6 +78,7 @@ import org.slf4j.LoggerFactory;
  * @author Robert Bausdorf - Initial contribution
  * @author Christoph Weitkamp - Added support for AVM FRITZ!DECT 300 and Comet DECT
  * @author Christoph Weitkamp - Added support for groups
+ * @author Ulrich Mertin - Added support for HAN-FUN blinds
  */
 @NonNullByDefault
 public abstract class AVMFritzBaseThingHandler extends BaseThingHandler implements FritzAhaStatusListener {
@@ -145,6 +151,9 @@ public abstract class AVMFritzBaseThingHandler extends BaseThingHandler implemen
                 if (deviceModel.isHANFUNAlarmSensor()) {
                     updateHANFUNAlarmSensor(deviceModel.getAlert());
                 }
+                if (deviceModel.isHANFUNBlinds()) {
+                    updateLevelcontrol(deviceModel.getLevelcontrol());
+                }
             }
         }
     }
@@ -172,6 +181,12 @@ public abstract class AVMFritzBaseThingHandler extends BaseThingHandler implemen
         }
     }
 
+    protected void updateLevelcontrol(@Nullable LevelcontrolModel levelcontrolModel) {
+        if (levelcontrolModel != null) {
+            updateThingChannelState(CHANNEL_ROLLERSHUTTER, new PercentType(levelcontrolModel.getLevelPercentage()));
+        }
+    }
+
     private void updateHeatingThermostat(@Nullable HeatingModel heatingModel) {
         if (heatingModel != null) {
             updateThingChannelState(CHANNEL_MODE, new StringType(heatingModel.getMode()));
@@ -424,6 +439,29 @@ public abstract class AVMFritzBaseThingHandler extends BaseThingHandler implemen
                     }
                 }
                 break;
+            case CHANNEL_ROLLERSHUTTER:
+                if (command instanceof StopMoveType) {
+                    StopMoveType rollershutterCommand = (StopMoveType) command;
+                    if (StopMoveType.STOP.equals(rollershutterCommand)) {
+                        fritzBox.setBlind(ain, BlindCommand.STOP);
+                    } else {
+                        logger.debug("Received unknown rollershutter StopMove command MOVE");
+                    }
+                } else if (command instanceof UpDownType) {
+                    UpDownType rollershutterCommand = (UpDownType) command;
+                    if (UpDownType.UP.equals(rollershutterCommand)) {
+                        fritzBox.setBlind(ain, BlindCommand.OPEN);
+                    } else {
+                        fritzBox.setBlind(ain, BlindCommand.CLOSE);
+                    }
+                } else if (command instanceof PercentType) {
+                    PercentType rollershutterCommand = (PercentType) command;
+                    BigDecimal levelpercentage = rollershutterCommand.toBigDecimal();
+                    fritzBox.setLevelpercentage(ain, levelpercentage);
+                } else {
+                    logger.debug("Received unknown rollershutter command type '{}'", command.toString());
+                }
+                break;
             default:
                 logger.debug("Received unknown channel {}", channelId);
                 break;
index 8eb2854acb8ac3c400eed53634697e38095d662c..4edc01fbec9062214173d3c3490813dea8a5f596 100644 (file)
@@ -33,6 +33,9 @@ import org.openhab.binding.avmfritz.internal.config.AVMFritzBoxConfiguration;
 import org.openhab.binding.avmfritz.internal.handler.AVMFritzBaseBridgeHandler;
 import org.openhab.binding.avmfritz.internal.hardware.callbacks.FritzAhaApplyTemplateCallback;
 import org.openhab.binding.avmfritz.internal.hardware.callbacks.FritzAhaCallback;
+import org.openhab.binding.avmfritz.internal.hardware.callbacks.FritzAhaSetBlindLevelCallback;
+import org.openhab.binding.avmfritz.internal.hardware.callbacks.FritzAhaSetBlindTargetCallback;
+import org.openhab.binding.avmfritz.internal.hardware.callbacks.FritzAhaSetBlindTargetCallback.BlindCommand;
 import org.openhab.binding.avmfritz.internal.hardware.callbacks.FritzAhaSetHeatingModeCallback;
 import org.openhab.binding.avmfritz.internal.hardware.callbacks.FritzAhaSetHeatingTemperatureCallback;
 import org.openhab.binding.avmfritz.internal.hardware.callbacks.FritzAhaSetSwitchCallback;
@@ -49,6 +52,7 @@ import org.slf4j.LoggerFactory;
  * @author Christoph Weitkamp - Added support for AVM FRITZ!DECT 300 and Comet
  *         DECT
  * @author Christoph Weitkamp - Added support for groups
+ * @author Ulrich Mertin - Added support for HAN-FUN blinds
  */
 @NonNullByDefault
 public class FritzAhaWebInterface {
@@ -319,4 +323,14 @@ public class FritzAhaWebInterface {
         FritzAhaSetHeatingModeCallback callback = new FritzAhaSetHeatingModeCallback(this, ain, command, endTime);
         return asyncGet(callback);
     }
+
+    public FritzAhaContentExchange setLevelpercentage(String ain, BigDecimal levelpercentage) {
+        FritzAhaSetBlindLevelCallback callback = new FritzAhaSetBlindLevelCallback(this, ain, levelpercentage);
+        return asyncGet(callback);
+    }
+
+    public FritzAhaContentExchange setBlind(String ain, BlindCommand command) {
+        FritzAhaSetBlindTargetCallback callback = new FritzAhaSetBlindTargetCallback(this, ain, command);
+        return asyncGet(callback);
+    }
 }
diff --git a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/hardware/callbacks/FritzAhaSetBlindLevelCallback.java b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/hardware/callbacks/FritzAhaSetBlindLevelCallback.java
new file mode 100644 (file)
index 0000000..430c0f2
--- /dev/null
@@ -0,0 +1,56 @@
+/**
+ * Copyright (c) 2010-2021 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.avmfritz.internal.hardware.callbacks;
+
+import static org.eclipse.jetty.http.HttpMethod.GET;
+
+import java.math.BigDecimal;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.binding.avmfritz.internal.hardware.FritzAhaWebInterface;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Callback implementation for updating blind commands. Supports reauthorization
+ *
+ * @author Ulrich Mertin - Initial contribution
+ */
+@NonNullByDefault
+public class FritzAhaSetBlindLevelCallback extends FritzAhaReauthCallback {
+
+    private final Logger logger = LoggerFactory.getLogger(FritzAhaSetBlindLevelCallback.class);
+
+    private final String ain;
+
+    /**
+     * Constructor
+     *
+     * @param webIface Interface to FRITZ!Box
+     * @param ain AIN of the device that should be switched
+     * @param level Opening level percentage (0 ... 100)
+     */
+    public FritzAhaSetBlindLevelCallback(FritzAhaWebInterface webIface, String ain, BigDecimal levelpercentage) {
+        super(WEBSERVICE_PATH, "switchcmd=setlevelpercentage&level=" + levelpercentage + "&ain=" + ain, webIface, GET,
+                1);
+        this.ain = ain;
+    }
+
+    @Override
+    public void execute(int status, String response) {
+        super.execute(status, response);
+        if (isValidRequest()) {
+            logger.debug("Received response '{}' for item '{}'", response, ain);
+        }
+    }
+}
diff --git a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/hardware/callbacks/FritzAhaSetBlindTargetCallback.java b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/hardware/callbacks/FritzAhaSetBlindTargetCallback.java
new file mode 100644 (file)
index 0000000..37a55cd
--- /dev/null
@@ -0,0 +1,69 @@
+/**
+ * Copyright (c) 2010-2021 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.avmfritz.internal.hardware.callbacks;
+
+import static org.eclipse.jetty.http.HttpMethod.GET;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.binding.avmfritz.internal.hardware.FritzAhaWebInterface;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Callback implementation for updating blind commands. Supports reauthorization
+ *
+ * @author Ulrich Mertin - Initial contribution
+ */
+@NonNullByDefault
+public class FritzAhaSetBlindTargetCallback extends FritzAhaReauthCallback {
+
+    private final Logger logger = LoggerFactory.getLogger(FritzAhaSetBlindTargetCallback.class);
+
+    private final String ain;
+
+    /**
+     * Constructor
+     *
+     * @param webIface Interface to FRITZ!Box
+     * @param ain AIN of the device that should be switched
+     * @param command Blind command to send
+     */
+    public FritzAhaSetBlindTargetCallback(FritzAhaWebInterface webIface, String ain, BlindCommand command) {
+        super(WEBSERVICE_PATH, "switchcmd=setblind&target=" + command.getTarget() + "&ain=" + ain, webIface, GET, 1);
+        this.ain = ain;
+    }
+
+    @Override
+    public void execute(int status, String response) {
+        super.execute(status, response);
+        if (isValidRequest()) {
+            logger.debug("Received response '{}' for item '{}'", response, ain);
+        }
+    }
+
+    public enum BlindCommand {
+        OPEN("open"),
+        CLOSE("close"),
+        STOP("stop");
+
+        private final String target;
+
+        private BlindCommand(final String target) {
+            this.target = target;
+        }
+
+        public String getTarget() {
+            return target;
+        }
+    }
+}
index d8728b93cf13c6950f6c827e26c99e04c539c167..b1543faacec6aa44d3cfc0fe8c4a2d1664d5b2e0 100644 (file)
@@ -99,6 +99,9 @@ thing-type.avmfritz.FRITZ_DECT_440.description = FRITZ!DECT 440 Taster. Dient zu
 
 thing-type.avmfritz.FRITZ_Powerline_546E.description = FRITZ!Powerline 546E schaltbare Steckdose. Dient zur Steuerung der integrierten Steckdose und liefert Daten wie z.B. Temperatur.
 
+thing-type.avmfritz.HAN_FUN_BLINDS.label = HAN-FUN Rolladen
+thing-type.avmfritz.HAN_FUN_BLINDS.description = HAN-FUN Rolladen (z.B. Rollotron DECT 1213).
+
 # thing types config groups
 thing-type.avmfritz.FRITZ_GROUP_HEATING.label = Heizkörperregler
 thing-type.avmfritz.FRITZ_GROUP_HEATING.description = Gruppe für Heizkörperregler. Dient zur Steuerung von Heizkörpern und liefert Daten wie z.B. Temperatur.
@@ -214,6 +217,9 @@ thing-type.avmfritz.FRITZ_DECT_400.channel.press.description = Wird ausgel
 thing-type.avmfritz.FRITZ_DECT_440.channel.press.label = Tastendruck
 thing-type.avmfritz.FRITZ_DECT_440.channel.press.description = Wird ausgelöst, wenn eine Taste gedrückt wird.
 
+channel-type.avmfritz.rollershutter.label = Rolladensteuerung
+channel-type.avmfritz.rollershutter.description = Steuert den Rolladen und zeigt seinen Öffnungsgrad in Prozent an.
+
 channel-type.avmfritz.last_change.label = Letzte Änderung
 channel-type.avmfritz.last_change.description = Zeigt an, wann der Schalter zuletzt gedrückt wurde.
 channel-type.avmfritz.last_change.pattern = %1$td.%1$tm.%1$tY %1$tH:%1$tM:%1$tS
index 87c6d3891bd3761e65432e07a928edd63e6d4b33..9c64ede171027fc230a8d5d22282a01ccb534de1 100644 (file)
                <category>Time</category>
                <state readOnly="true"/>
        </channel-type>
+
+       <channel-type id="rollershutter">
+               <item-type>Rollershutter</item-type>
+               <label>Rollershutter Control</label>
+               <description>Controls the rollershutter and states its opening level in percent</description>
+               <category>Blinds</category>
+       </channel-type>
+
 </thing:thing-descriptions>
index 3921f4948b5079298d92ba09065f06339fb4f2ac..bdf606ed242c18957043fb7aa6622cc56e182991 100644 (file)
                <config-description-ref uri="thing-type:avmfritz:fritzdevice"/>
        </thing-type>
 
+       <thing-type id="HAN_FUN_BLINDS">
+               <supported-bridge-type-refs>
+                       <bridge-type-ref id="fritzbox"/>
+                       <bridge-type-ref id="FRITZ_Powerline_546E_Solo"/>
+               </supported-bridge-type-refs>
+
+               <label>HAN-FUN Blinds</label>
+               <description>HAN-FUN blinds (e.g. RolloTron DECT 1213)</description>
+
+               <channels>
+                       <channel id="rollershutter" typeId="rollershutter"/>
+               </channels>
+
+               <representation-property>ain</representation-property>
+
+               <config-description-ref uri="thing-type:avmfritz:fritzdevice"/>
+       </thing-type>
+
        <!-- Supported FRITZ! groups and features -->
        <thing-type id="FRITZ_GROUP_HEATING">
                <supported-bridge-type-refs>
index a6a3aca56f9a6a4e4035cc05a18a24d18466e3d1..3606d52ef6a0f168b3e5aa4adf77ed9404d00b0b 100644 (file)
@@ -33,6 +33,7 @@ import org.slf4j.LoggerFactory;
  * Tests for {@link DeviceListModel}.
  *
  * @author Christoph Weitkamp - Initial contribution
+ * @author Ulrich Mertin - Added support for HAN-FUN blinds
  */
 @NonNullByDefault
 public class AVMFritzDeviceListModelTest {
@@ -59,6 +60,7 @@ public class AVMFritzDeviceListModelTest {
                     "<device identifier=\"11934 0059979-1\" id=\"2001\" functionbitmask=\"8200\" fwversion=\"0.0\" manufacturer=\"0x0feb\" productname=\"HAN-FUN\"><present>0</present><name>HAN-FUN #2: Unit #2</name><etsiunitinfo><etsideviceid>412</etsideviceid><unittype>273</unittype><interfaces>772</interfaces></etsiunitinfo><button><lastpressedtimestamp>1529590797</lastpressedtimestamp></button></device>" +
                     "<device identifier=\"13096 0007307\" id=\"29\" functionbitmask=\"32\" fwversion=\"04.90\" manufacturer=\"AVM\" productname=\"FRITZ!DECT 400\"><present>1</present><name>FRITZ!DECT 400 #14</name><battery>100</battery><batterylow>0</batterylow><button identifier=\"13096 0007307-0\" id=\"5000\"><name>FRITZ!DECT 400 #14: kurz</name><lastpressedtimestamp>1549195586</lastpressedtimestamp></button><button identifier=\"13096 0007307-9\" id=\"5001\"><name>FRITZ!DECT 400 #14: lang</name><lastpressedtimestamp>1549195595</lastpressedtimestamp></button></device>" +
                     "<device identifier=\"13096 0007308\" id=\"30\" functionbitmask=\"1048864\" fwversion=\"05.10\" manufacturer=\"AVM\" productname=\"FRITZ!DECT 440\"><present>1</present><name>FRITZ!DECT 440 #15</name><temperature><celsius>230</celsius><offset>0</offset></temperature><humidity><rel_humidity>43</rel_humidity></humidity><battery>100</battery><batterylow>0</batterylow><button identifier=\"13096 0007308-1\" id=\"5000\"><name>FRITZ!DECT 440 #15: Oben rechts</name><lastpressedtimestamp>1549195586</lastpressedtimestamp></button><button identifier=\"13096 0007308-3\" id=\"5001\"><name>FRITZ!DECT 440 #15: Unten rechts</name><lastpressedtimestamp>1549195595</lastpressedtimestamp></button><button identifier=\"13096 0007308-5\" id=\"5002\"><name>FRITZ!DECT 440 #15: Unten links</name><lastpressedtimestamp>1549195586</lastpressedtimestamp></button><button identifier=\"13096 0007308-7\" id=\"5003\"><name>FRITZ!DECT 440 #15: Oben links</name><lastpressedtimestamp>1549195595</lastpressedtimestamp></button></device>" +
+                    "<device identifier=\"14276 0503450-1\" id=\"2000\" functionbitmask=\"335888\" fwversion=\"0.0\" manufacturer=\"0x37c4\" productname=\"Rollotron 1213\"><present>1</present><txbusy>0</txbusy><name>Rollotron 1213 #1</name><blind><endpositionsset>1</endpositionsset><mode>manuell</mode></blind><levelcontrol><level>26</level><levelpercentage>10</levelpercentage></levelcontrol><etsiunitinfo><etsideviceid>406</etsideviceid><unittype>281</unittype><interfaces>256,513,516,517</interfaces></etsiunitinfo><alert><state>0</state><lastalertchgtimestamp></lastalertchgtimestamp></alert></device>" +
                 "</devicelist>";
         //@formatter:off
         try {
@@ -72,7 +74,7 @@ public class AVMFritzDeviceListModelTest {
     @Test
     public void validateDeviceListModel() {
         assertNotNull(devices);
-        assertEquals(13, devices.getDevicelist().size());
+        assertEquals(14, devices.getDevicelist().size());
         assertEquals("1", devices.getXmlApiVersion());
     }
 
@@ -101,6 +103,7 @@ public class AVMFritzDeviceListModelTest {
         assertFalse(device.isHumiditySensor());
         assertFalse(device.isPowermeter());
         assertFalse(device.isHeatingThermostat());
+        assertFalse(device.isHANFUNBlinds());
 
         assertNull(device.getSwitch());
 
@@ -111,6 +114,8 @@ public class AVMFritzDeviceListModelTest {
         assertNull(device.getPowermeter());
 
         assertNull(device.getHkr());
+
+        assertNull(device.getLevelcontrol());
     }
 
     @Test
@@ -138,6 +143,7 @@ public class AVMFritzDeviceListModelTest {
         assertFalse(device.isHumiditySensor());
         assertTrue(device.isPowermeter());
         assertFalse(device.isHeatingThermostat());
+        assertFalse(device.isHANFUNBlinds());
 
         assertNotNull(device.getSwitch());
         assertEquals(SwitchModel.ON, device.getSwitch().getState());
@@ -152,6 +158,8 @@ public class AVMFritzDeviceListModelTest {
         validatePowerMeter(device.getPowermeter());
 
         assertNull(device.getHkr());
+
+        assertNull(device.getLevelcontrol());
     }
 
     @Test
@@ -179,6 +187,7 @@ public class AVMFritzDeviceListModelTest {
         assertFalse(device.isHumiditySensor());
         assertTrue(device.isPowermeter());
         assertFalse(device.isHeatingThermostat());
+        assertFalse(device.isHANFUNBlinds());
 
         assertNotNull(device.getSwitch());
         assertEquals(SwitchModel.ON, device.getSwitch().getState());
@@ -193,6 +202,8 @@ public class AVMFritzDeviceListModelTest {
         validatePowerMeter(device.getPowermeter());
 
         assertNull(device.getHkr());
+
+        assertNull(device.getLevelcontrol());
     }
 
     @Test
@@ -220,6 +231,7 @@ public class AVMFritzDeviceListModelTest {
         assertFalse(device.isHumiditySensor());
         assertFalse(device.isPowermeter());
         assertTrue(device.isHeatingThermostat());
+        assertFalse(device.isHANFUNBlinds());
 
         assertNull(device.getSwitch());
 
@@ -257,6 +269,7 @@ public class AVMFritzDeviceListModelTest {
         assertFalse(device.isHumiditySensor());
         assertFalse(device.isPowermeter());
         assertTrue(device.isHeatingThermostat());
+        assertFalse(device.isHANFUNBlinds());
 
         assertNull(device.getSwitch());
 
@@ -294,6 +307,7 @@ public class AVMFritzDeviceListModelTest {
         assertFalse(device.isHumiditySensor());
         assertFalse(device.isPowermeter());
         assertTrue(device.isHeatingThermostat());
+        assertFalse(device.isHANFUNBlinds());
 
         assertNull(device.getSwitch());
 
@@ -331,6 +345,7 @@ public class AVMFritzDeviceListModelTest {
         assertFalse(device.isHumiditySensor());
         assertFalse(device.isPowermeter());
         assertFalse(device.isHeatingThermostat());
+        assertFalse(device.isHANFUNBlinds());
 
         assertEquals(new BigDecimal("100"), device.getBattery());
         assertEquals(BatteryModel.BATTERY_OFF, device.getBatterylow());
@@ -350,6 +365,8 @@ public class AVMFritzDeviceListModelTest {
         assertNull(device.getPowermeter());
 
         assertNull(device.getHkr());
+
+        assertNull(device.getLevelcontrol());
     }
 
     @Test
@@ -377,6 +394,7 @@ public class AVMFritzDeviceListModelTest {
         assertTrue(device.isHumiditySensor());
         assertFalse(device.isPowermeter());
         assertFalse(device.isHeatingThermostat());
+        assertFalse(device.isHANFUNBlinds());
 
         assertEquals(new BigDecimal("100"), device.getBattery());
         assertEquals(BatteryModel.BATTERY_OFF, device.getBatterylow());
@@ -417,6 +435,8 @@ public class AVMFritzDeviceListModelTest {
         assertNull(device.getPowermeter());
 
         assertNull(device.getHkr());
+
+        assertNull(device.getLevelcontrol());
     }
 
     @Test
@@ -444,6 +464,7 @@ public class AVMFritzDeviceListModelTest {
         assertFalse(device.isHumiditySensor());
         assertTrue(device.isPowermeter());
         assertFalse(device.isHeatingThermostat());
+        assertFalse(device.isHANFUNBlinds());
 
         assertNotNull(device.getSwitch());
         assertEquals(SwitchModel.OFF, device.getSwitch().getState());
@@ -456,6 +477,8 @@ public class AVMFritzDeviceListModelTest {
         validatePowerMeter(device.getPowermeter());
 
         assertNull(device.getHkr());
+
+        assertNull(device.getLevelcontrol());
     }
 
     @Test
@@ -483,6 +506,7 @@ public class AVMFritzDeviceListModelTest {
         assertFalse(device.isHumiditySensor());
         assertFalse(device.isPowermeter());
         assertFalse(device.isHeatingThermostat());
+        assertFalse(device.isHANFUNBlinds());
 
         assertTrue(device.getButtons().isEmpty());
 
@@ -496,6 +520,8 @@ public class AVMFritzDeviceListModelTest {
         assertNull(device.getPowermeter());
 
         assertNull(device.getHkr());
+
+        assertNull(device.getLevelcontrol());
     }
 
     @Test
@@ -523,6 +549,7 @@ public class AVMFritzDeviceListModelTest {
         assertFalse(device.isHumiditySensor());
         assertFalse(device.isPowermeter());
         assertFalse(device.isHeatingThermostat());
+        assertFalse(device.isHANFUNBlinds());
 
         assertEquals(1, device.getButtons().size());
         assertEquals(1529590797, device.getButtons().get(0).getLastpressedtimestamp());
@@ -536,6 +563,54 @@ public class AVMFritzDeviceListModelTest {
         assertNull(device.getPowermeter());
 
         assertNull(device.getHkr());
+
+        assertNull(device.getLevelcontrol());
+    }
+
+    @Test
+    public void validateHANFUNBlindModel() {
+        Optional<AVMFritzBaseModel> optionalDevice = findModelByIdentifier("142760503450-1");
+        assertTrue(optionalDevice.isPresent());
+        assertTrue(optionalDevice.get() instanceof DeviceModel);
+
+        DeviceModel device = (DeviceModel) optionalDevice.get();
+        assertEquals("Rollotron 1213", device.getProductName());
+        assertEquals("142760503450-1", device.getIdentifier());
+        assertEquals("2000", device.getDeviceId());
+        assertEquals("0.0", device.getFirmwareVersion());
+        assertEquals("0x37c4", device.getManufacturer());
+
+        assertEquals(1, device.getPresent());
+        assertEquals("Rollotron 1213 #1", device.getName());
+
+        assertFalse(device.isButton());
+        assertFalse(device.isHANFUNButton());
+        assertTrue(device.isHANFUNAlarmSensor());
+        assertFalse(device.isDectRepeater());
+        assertFalse(device.isSwitchableOutlet());
+        assertFalse(device.isTempSensor());
+        assertFalse(device.isHumiditySensor());
+        assertFalse(device.isPowermeter());
+        assertFalse(device.isHeatingThermostat());
+        assertTrue(device.isHANFUNBlinds());
+
+        assertTrue(device.getButtons().isEmpty());
+
+        assertNotNull(device.getAlert());
+        assertEquals(BigDecimal.ZERO, device.getAlert().getState());
+
+        assertNull(device.getSwitch());
+
+        assertNull(device.getTemperature());
+
+        assertNull(device.getPowermeter());
+
+        assertNull(device.getHkr());
+
+        LevelcontrolModel levelcontrol = device.getLevelcontrol();
+        assertNotNull(levelcontrol);
+        assertEquals(BigDecimal.valueOf(26L), levelcontrol.getLevel());
+        assertEquals(BigDecimal.valueOf(10L), levelcontrol.getLevelPercentage());
     }
 
     @Test
@@ -563,6 +638,7 @@ public class AVMFritzDeviceListModelTest {
         assertFalse(group.isHumiditySensor());
         assertFalse(group.isPowermeter());
         assertTrue(group.isHeatingThermostat());
+        assertFalse(group.isHANFUNBlinds());
 
         assertNull(group.getSwitch());
 
@@ -600,6 +676,7 @@ public class AVMFritzDeviceListModelTest {
         assertFalse(group.isHumiditySensor());
         assertTrue(group.isPowermeter());
         assertFalse(group.isHeatingThermostat());
+        assertFalse(group.isHANFUNBlinds());
 
         assertNotNull(group.getSwitch());
         assertEquals(SwitchModel.ON, group.getSwitch().getState());
index 53bb026f22c83af8bd8d557baf1d50417f9efc5b..c5e5fd5d1f5f76c526ac318854b18c7c9503ac73 100644 (file)
@@ -43,6 +43,7 @@ import org.openhab.core.thing.ThingUID;
  * Tests for {@link AVMFritzDiscoveryService}.
  *
  * @author Christoph Weitkamp - Initial contribution
+ * @author Ulrich Mertin - Added support for HAN-FUN blinds
  */
 @NonNullByDefault
 public class AVMFritzDiscoveryServiceOSGiTest extends AVMFritzThingHandlerOSGiTest {
@@ -86,7 +87,7 @@ public class AVMFritzDiscoveryServiceOSGiTest extends AVMFritzThingHandlerOSGiTe
 
     @Test
     public void correctSupportedTypes() {
-        assertEquals(13, discovery.getSupportedThingTypes().size());
+        assertEquals(14, discovery.getSupportedThingTypes().size());
         assertTrue(discovery.getSupportedThingTypes().contains(DECT100_THING_TYPE));
         assertTrue(discovery.getSupportedThingTypes().contains(DECT200_THING_TYPE));
         assertTrue(discovery.getSupportedThingTypes().contains(DECT210_THING_TYPE));
@@ -98,6 +99,7 @@ public class AVMFritzDiscoveryServiceOSGiTest extends AVMFritzThingHandlerOSGiTe
         assertTrue(discovery.getSupportedThingTypes().contains(COMETDECT_THING_TYPE));
         assertTrue(discovery.getSupportedThingTypes().contains(HAN_FUN_CONTACT_THING_TYPE));
         assertTrue(discovery.getSupportedThingTypes().contains(HAN_FUN_SWITCH_THING_TYPE));
+        assertTrue(discovery.getSupportedThingTypes().contains(HAN_FUN_BLINDS_THING_TYPE));
         assertTrue(discovery.getSupportedThingTypes().contains(GROUP_HEATING_THING_TYPE));
         assertTrue(discovery.getSupportedThingTypes().contains(GROUP_SWITCH_THING_TYPE));
     }
@@ -727,6 +729,59 @@ public class AVMFritzDiscoveryServiceOSGiTest extends AVMFritzThingHandlerOSGiTe
         assertEquals(CONFIG_AIN, discoveryResult.getRepresentationProperty());
     }
 
+    @Test
+    public void validHANFUNBlindDiscoveryResult() throws JAXBException {
+        //@formatter:off
+        String xml =
+                "<devicelist version=\"1\">" +
+                    "<device identifier=\"14276 0503450-1\" id=\"2000\" functionbitmask=\"335888\" fwversion=\"0.0\" manufacturer=\"0x37c4\" productname=\"Rollotron 1213\">"+
+                        "<present>1</present>"+
+                        "<txbusy>0</txbusy>"+
+                        "<name>Rollotron 1213 #1</name>"+
+                        "<blind>"+
+                            "<endpositionsset>1</endpositionsset>"+
+                            "<mode>manuell</mode>"+
+                        "</blind>"+
+                        "<levelcontrol>"+
+                            "<level>26</level>"+
+                            "<levelpercentage>10</levelpercentage>"+
+                        "</levelcontrol>"+
+                        "<etsiunitinfo>"+
+                            "<etsideviceid>406</etsideviceid>"+
+                            "<unittype>281</unittype>"+
+                            "<interfaces>256,513,516,517</interfaces>"+
+                        "</etsiunitinfo>"+
+                        "<alert>"+
+                            "<state>0</state>"+
+                            "<lastalertchgtimestamp></lastalertchgtimestamp>"+
+                        "</alert>"+
+                    "</device>" +
+                "</devicelist>";
+        //@formatter:on
+
+        Unmarshaller u = JAXBUtils.JAXBCONTEXT_DEVICES.createUnmarshaller();
+        DeviceListModel devices = (DeviceListModel) u.unmarshal(new StringReader(xml));
+        assertNotNull(devices);
+        assertEquals(1, devices.getDevicelist().size());
+
+        AVMFritzBaseModel device = devices.getDevicelist().get(0);
+        assertNotNull(device);
+
+        discovery.onDeviceAdded(device);
+        assertNotNull(discoveryResult);
+
+        assertEquals(DiscoveryResultFlag.NEW, discoveryResult.getFlag());
+        assertEquals(new ThingUID("avmfritz:HAN_FUN_BLINDS:1:142760503450_1"), discoveryResult.getThingUID());
+        assertEquals(HAN_FUN_BLINDS_THING_TYPE, discoveryResult.getThingTypeUID());
+        assertEquals(BRIGE_THING_ID, discoveryResult.getBridgeUID());
+        assertEquals("142760503450-1", discoveryResult.getProperties().get(CONFIG_AIN));
+        assertEquals("0x37c4", discoveryResult.getProperties().get(PROPERTY_VENDOR));
+        assertEquals("Rollotron 1213", discoveryResult.getProperties().get(PRODUCT_NAME));
+        assertEquals("142760503450-1", discoveryResult.getProperties().get(PROPERTY_SERIAL_NUMBER));
+        assertEquals("0.0", discoveryResult.getProperties().get(PROPERTY_FIRMWARE_VERSION));
+        assertEquals(CONFIG_AIN, discoveryResult.getRepresentationProperty());
+    }
+
     @Test
     public void validHeatingGroupDiscoveryResult() throws JAXBException {
         //@formatter:off