Added humidity channel, minor fixes ()

Signed-off-by: Christoph Weitkamp <github@christophweitkamp.de>
This commit is contained in:
Christoph Weitkamp 2020-12-22 20:55:08 +01:00 committed by GitHub
parent 54ca612630
commit 2c6e15bb02
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 144 additions and 22 deletions
bundles/org.openhab.binding.avmfritz

@ -169,6 +169,7 @@ The AIN (actor identification number) can be found in the FRITZ!Box interface ->
| locked | Contact | Device is locked for switching over external sources (OPEN/CLOSE) | FRITZ!DECT 210, FRITZ!DECT 200, FRITZ!Powerline 546E, FRITZ!DECT 301, FRITZ!DECT 300, Comet DECT |
| device_locked | Contact | Device is locked for switching manually (OPEN/CLOSE) - FRITZ!OS 6.90 | FRITZ!DECT 210, FRITZ!DECT 200, FRITZ!Powerline 546E, FRITZ!DECT 301, FRITZ!DECT 300, Comet DECT |
| temperature | Number:Temperature | Current measured temperature | FRITZ!DECT 210, FRITZ!DECT 200, FRITZ!DECT Repeater 100, FRITZ!DECT 301, FRITZ!DECT 300, Comet DECT, FRITZ!DECT 440 |
| humidity | Number:Dimensionless | Current measured humidity - FRITZ!OS 7.24 | FRITZ!DECT 440 |
| energy | Number:Energy | Accumulated energy consumption | FRITZ!DECT 210, FRITZ!DECT 200, FRITZ!Powerline 546E |
| power | Number:Power | Current power consumption | FRITZ!DECT 210, FRITZ!DECT 200, FRITZ!Powerline 546E |
| voltage | Number:ElectricPotential | Current voltage - FRITZ!OS 7 | FRITZ!DECT 210, FRITZ!DECT 200, FRITZ!Powerline 546E |

@ -89,6 +89,7 @@ public class AVMFritzBindingConstants {
public static final String PROPERTY_MEMBERS = "members";
// List of all channel groups
public static final String CHANNEL_GROUP_SENSORS = "sensors";
public static final String CHANNEL_GROUP_TOP_LEFT = "top-left";
public static final String CHANNEL_GROUP_BOTTOM_LEFT = "bottom-left";
public static final String CHANNEL_GROUP_TOP_RIGHT = "top-right";
@ -105,6 +106,7 @@ public class AVMFritzBindingConstants {
public static final String CHANNEL_DEVICE_LOCKED = "device_locked";
public static final String CHANNEL_APPLY_TEMPLATE = "apply_template";
public static final String CHANNEL_TEMPERATURE = "temperature";
public static final String CHANNEL_HUMIDITY = "humidity";
public static final String CHANNEL_ENERGY = "energy";
public static final String CHANNEL_POWER = "power";
public static final String CHANNEL_VOLTAGE = "voltage";

@ -47,11 +47,12 @@ public abstract class AVMFritzBaseModel implements BatteryModel {
protected static final int BUTTON_BIT = 1 << 5; // Bit 5
protected static final int HEATING_THERMOSTAT_BIT = 1 << 6; // Bit 6
protected static final int POWERMETER_BIT = 1 << 7; // Bit 7
protected static final int TEMPSENSOR_BIT = 1 << 8; // Bit 8
protected static final int TEMPERATURE_SENSOR_BIT = 1 << 8; // Bit 8
protected static final int OUTLET_BIT = 1 << 9; // Bit 9
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 HUMIDITY_SENSOR_BIT = 1 << 20; // Bit 20 - undocumented
@XmlAttribute(name = "identifier")
private String ident;
@ -149,7 +150,11 @@ public abstract class AVMFritzBaseModel implements BatteryModel {
}
public boolean isTempSensor() {
return (bitmask & TEMPSENSOR_BIT) > 0;
return (bitmask & TEMPERATURE_SENSOR_BIT) > 0;
}
public boolean isHumiditySensor() {
return (bitmask & HUMIDITY_SENSOR_BIT) > 0;
}
public boolean isPowermeter() {
@ -208,13 +213,14 @@ public abstract class AVMFritzBaseModel implements BatteryModel {
.append(",isHANFUNDevice=").append(isHANFUNDevice()).append(",isHANFUNButton=").append(isHANFUNButton())
.append(",isHANFUNAlarmSensor=").append(isHANFUNAlarmSensor()).append(",isButton=").append(isButton())
.append(",isSwitchableOutlet=").append(isSwitchableOutlet()).append(",isTempSensor=")
.append(isTempSensor()).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(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();
}
}

@ -12,7 +12,6 @@
*/
package org.openhab.binding.avmfritz.internal.dto;
import java.util.Collections;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
@ -31,6 +30,7 @@ import javax.xml.bind.annotation.XmlType;
public class DeviceModel extends AVMFritzBaseModel {
private TemperatureModel temperature;
private HumidityModel humidity;
private AlertModel alert;
@XmlElement(name = "button", type = ButtonModel.class)
@ -46,6 +46,14 @@ public class DeviceModel extends AVMFritzBaseModel {
this.temperature = temperatureModel;
}
public HumidityModel getHumidity() {
return humidity;
}
public void setTemperature(HumidityModel humidityModel) {
this.humidity = humidityModel;
}
public AlertModel getAlert() {
return alert;
}
@ -55,10 +63,7 @@ public class DeviceModel extends AVMFritzBaseModel {
}
public List<ButtonModel> getButtons() {
if (buttons == null) {
return Collections.emptyList();
}
return buttons;
return buttons == null ? List.of() : buttons;
}
public void setButtons(List<ButtonModel> buttons) {
@ -75,8 +80,8 @@ public class DeviceModel extends AVMFritzBaseModel {
@Override
public String toString() {
return new StringBuilder().append(super.toString()).append(temperature).append(",").append(alert).append(",")
.append(getButtons()).append(",").append(etsiunitinfo).append("]").toString();
return new StringBuilder().append(super.toString()).append(temperature).append(",").append(humidity).append(",")
.append(alert).append(",").append(getButtons()).append(",").append(etsiunitinfo).append("]").toString();
}
@XmlAccessorType(XmlAccessType.FIELD)

@ -0,0 +1,46 @@
/**
* 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.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 Christoph Weitkamp - Initial contribution
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "humidity")
public class HumidityModel {
@XmlElement(name = "rel_humidity")
private BigDecimal relativeHumidity;
public BigDecimal getRelativeHumidity() {
return relativeHumidity != null ? relativeHumidity : BigDecimal.ZERO;
}
public void setRelativeHumidity(BigDecimal relativeHumidity) {
this.relativeHumidity = relativeHumidity;
}
@Override
public String toString() {
return new StringBuilder().append("[rel_humidity=").append(getRelativeHumidity()).append("]").toString();
}
}

@ -32,6 +32,7 @@ import org.openhab.binding.avmfritz.internal.dto.BatteryModel;
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.PowerMeterModel;
import org.openhab.binding.avmfritz.internal.dto.SwitchModel;
import org.openhab.binding.avmfritz.internal.dto.TemperatureModel;
@ -138,6 +139,9 @@ public abstract class AVMFritzBaseThingHandler extends BaseThingHandler implemen
if (deviceModel.isTempSensor()) {
updateTemperatureSensor(deviceModel.getTemperature());
}
if (deviceModel.isHumiditySensor()) {
updateHumiditySensor(deviceModel.getHumidity());
}
if (deviceModel.isHANFUNAlarmSensor()) {
updateHANFUNAlarmSensor(deviceModel.getAlert());
}
@ -161,6 +165,13 @@ public abstract class AVMFritzBaseThingHandler extends BaseThingHandler implemen
}
}
protected void updateHumiditySensor(@Nullable HumidityModel humidityModel) {
if (humidityModel != null) {
updateThingChannelState(CHANNEL_HUMIDITY,
new QuantityType<>(humidityModel.getRelativeHumidity(), Units.PERCENT));
}
}
private void updateHeatingThermostat(@Nullable HeatingModel heatingModel) {
if (heatingModel != null) {
updateThingChannelState(CHANNEL_MODE, new StringType(heatingModel.getMode()));
@ -255,6 +266,19 @@ public abstract class AVMFritzBaseThingHandler extends BaseThingHandler implemen
}
}
/**
* Creates a {@link ChannelTypeUID} from the given channel id.
*
* @param channelId ID of the channel type UID to be created.
* @return the channel type UID
*/
private ChannelTypeUID createChannelTypeUID(String channelId) {
int pos = channelId.indexOf(ChannelUID.CHANNEL_GROUP_SEPARATOR);
String id = pos > -1 ? channelId.substring(pos + 1) : channelId;
return CHANNEL_BATTERY.equals(id) ? DefaultSystemChannelTypeProvider.SYSTEM_CHANNEL_BATTERY_LEVEL.getUID()
: new ChannelTypeUID(BINDING_ID, id);
}
/**
* Creates new channels for the thing.
*
@ -264,9 +288,7 @@ public abstract class AVMFritzBaseThingHandler extends BaseThingHandler implemen
ThingHandlerCallback callback = getCallback();
if (callback != null) {
ChannelUID channelUID = new ChannelUID(thing.getUID(), channelId);
ChannelTypeUID channelTypeUID = CHANNEL_BATTERY.equals(channelId)
? DefaultSystemChannelTypeProvider.SYSTEM_CHANNEL_BATTERY_LEVEL.getUID()
: new ChannelTypeUID(BINDING_ID, channelId);
ChannelTypeUID channelTypeUID = createChannelTypeUID(channelId);
Channel channel = callback.createChannelBuilder(channelUID, channelTypeUID).build();
updateThing(editThing().withoutChannel(channelUID).withChannel(channel).build());
}
@ -317,6 +339,7 @@ public abstract class AVMFritzBaseThingHandler extends BaseThingHandler implemen
case CHANNEL_LOCKED:
case CHANNEL_DEVICE_LOCKED:
case CHANNEL_TEMPERATURE:
case CHANNEL_HUMIDITY:
case CHANNEL_ENERGY:
case CHANNEL_POWER:
case CHANNEL_VOLTAGE:

@ -25,7 +25,10 @@ import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.avmfritz.internal.dto.AVMFritzBaseModel;
import org.openhab.binding.avmfritz.internal.dto.ButtonModel;
import org.openhab.binding.avmfritz.internal.dto.DeviceModel;
import org.openhab.binding.avmfritz.internal.dto.HumidityModel;
import org.openhab.core.library.types.DateTimeType;
import org.openhab.core.library.types.QuantityType;
import org.openhab.core.library.unit.Units;
import org.openhab.core.thing.Channel;
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.CommonTriggerEvents;
@ -86,6 +89,14 @@ public class AVMFritzButtonHandler extends DeviceHandler {
}
}
@Override
protected void updateHumiditySensor(@Nullable HumidityModel humidityModel) {
if (humidityModel != null) {
updateThingChannelState(CHANNEL_GROUP_SENSORS + ChannelUID.CHANNEL_GROUP_SEPARATOR + CHANNEL_HUMIDITY,
new QuantityType<>(humidityModel.getRelativeHumidity(), Units.PERCENT));
}
}
private void updateShortLongPressButton(List<ButtonModel> buttons) {
ButtonModel shortPressButton = buttons.size() > 0 ? buttons.get(0) : null;
ButtonModel longPressButton = buttons.size() > 1 ? buttons.get(1) : null;

@ -159,6 +159,9 @@ channel-type.avmfritz.apply_template.description = Erm
channel-type.avmfritz.temperature.label = Temperatur
channel-type.avmfritz.temperature.description = Zeigt die aktuelle Temperatur an.
channel-type.avmfritz.humidity.label = Luftfeuchtigkeit
channel-type.avmfritz.humidity.description = Zeigt die aktuelle Luftfeuchtigkeit an.
channel-type.avmfritz.energy.label = Gesamtverbrauch
channel-type.avmfritz.energy.description = Zeigt den akkumulierten Gesamtverbrauch an.

@ -97,6 +97,7 @@
<label>Sensor Data</label>
<channels>
<channel id="temperature" typeId="temperature"/>
<channel id="humidity" typeId="humidity"/>
</channels>
</channel-group-type>
@ -111,6 +112,14 @@
<config-description-ref uri="channel-type:avmfritz:temperature"/>
</channel-type>
<channel-type id="humidity">
<item-type>Number:Dimensionless</item-type>
<label>Current Humidity</label>
<description>Current measured humidity.</description>
<category>Humidity</category>
<state pattern="%.0f %unit%" readOnly="true"/>
</channel-type>
<channel-type id="energy">
<item-type>Number:Energy</item-type>
<label>Energy Consumption</label>

@ -58,7 +58,7 @@ public class AVMFritzDeviceListModelTest {
"<device identifier=\"11934 0059978-1\" id=\"2000\" functionbitmask=\"8208\" fwversion=\"0.0\" manufacturer=\"0x0feb\" productname=\"HAN-FUN\"><present>0</present><name>HAN-FUN #2: Unit #2</name><etsiunitinfo><etsideviceid>406</etsideviceid><unittype>514</unittype><interfaces>256</interfaces></etsiunitinfo><alert><state>1</state></alert></device>" +
"<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=\"288\" fwversion=\"04.90\" manufacturer=\"AVM\" productname=\"FRITZ!DECT 440\"><present>1</present><name>FRITZ!DECT 440 #15</name><temperature><celsius>230</celsius><offset>0</offset></temperature><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=\"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>" +
"</devicelist>";
//@formatter:off
try {
@ -98,6 +98,7 @@ public class AVMFritzDeviceListModelTest {
assertTrue(device.isDectRepeater());
assertFalse(device.isSwitchableOutlet());
assertTrue(device.isTempSensor());
assertFalse(device.isHumiditySensor());
assertFalse(device.isPowermeter());
assertFalse(device.isHeatingThermostat());
@ -134,6 +135,7 @@ public class AVMFritzDeviceListModelTest {
assertFalse(device.isDectRepeater());
assertTrue(device.isSwitchableOutlet());
assertTrue(device.isTempSensor());
assertFalse(device.isHumiditySensor());
assertTrue(device.isPowermeter());
assertFalse(device.isHeatingThermostat());
@ -174,6 +176,7 @@ public class AVMFritzDeviceListModelTest {
assertFalse(device.isDectRepeater());
assertTrue(device.isSwitchableOutlet());
assertTrue(device.isTempSensor());
assertFalse(device.isHumiditySensor());
assertTrue(device.isPowermeter());
assertFalse(device.isHeatingThermostat());
@ -214,6 +217,7 @@ public class AVMFritzDeviceListModelTest {
assertFalse(device.isDectRepeater());
assertFalse(device.isSwitchableOutlet());
assertTrue(device.isTempSensor());
assertFalse(device.isHumiditySensor());
assertFalse(device.isPowermeter());
assertTrue(device.isHeatingThermostat());
@ -250,6 +254,7 @@ public class AVMFritzDeviceListModelTest {
assertFalse(device.isDectRepeater());
assertFalse(device.isSwitchableOutlet());
assertTrue(device.isTempSensor());
assertFalse(device.isHumiditySensor());
assertFalse(device.isPowermeter());
assertTrue(device.isHeatingThermostat());
@ -286,6 +291,7 @@ public class AVMFritzDeviceListModelTest {
assertFalse(device.isDectRepeater());
assertFalse(device.isSwitchableOutlet());
assertTrue(device.isTempSensor());
assertFalse(device.isHumiditySensor());
assertFalse(device.isPowermeter());
assertTrue(device.isHeatingThermostat());
@ -322,6 +328,7 @@ public class AVMFritzDeviceListModelTest {
assertFalse(device.isDectRepeater());
assertFalse(device.isSwitchableOutlet());
assertFalse(device.isTempSensor());
assertFalse(device.isHumiditySensor());
assertFalse(device.isPowermeter());
assertFalse(device.isHeatingThermostat());
@ -355,7 +362,7 @@ public class AVMFritzDeviceListModelTest {
assertEquals("FRITZ!DECT 440", device.getProductName());
assertEquals("130960007308", device.getIdentifier());
assertEquals("30", device.getDeviceId());
assertEquals("04.90", device.getFirmwareVersion());
assertEquals("05.10", device.getFirmwareVersion());
assertEquals("AVM", device.getManufacturer());
assertEquals(1, device.getPresent());
@ -367,6 +374,7 @@ public class AVMFritzDeviceListModelTest {
assertFalse(device.isDectRepeater());
assertFalse(device.isSwitchableOutlet());
assertTrue(device.isTempSensor());
assertTrue(device.isHumiditySensor());
assertFalse(device.isPowermeter());
assertFalse(device.isHeatingThermostat());
@ -403,6 +411,9 @@ public class AVMFritzDeviceListModelTest {
assertEquals(new BigDecimal("23.0"), device.getTemperature().getCelsius());
assertEquals(new BigDecimal("0.0"), device.getTemperature().getOffset());
assertNotNull(device.getHumidity());
assertEquals(new BigDecimal("43"), device.getHumidity().getRelativeHumidity());
assertNull(device.getPowermeter());
assertNull(device.getHkr());
@ -430,6 +441,7 @@ public class AVMFritzDeviceListModelTest {
assertFalse(device.isDectRepeater());
assertTrue(device.isSwitchableOutlet());
assertFalse(device.isTempSensor());
assertFalse(device.isHumiditySensor());
assertTrue(device.isPowermeter());
assertFalse(device.isHeatingThermostat());
@ -468,6 +480,7 @@ public class AVMFritzDeviceListModelTest {
assertFalse(device.isDectRepeater());
assertFalse(device.isSwitchableOutlet());
assertFalse(device.isTempSensor());
assertFalse(device.isHumiditySensor());
assertFalse(device.isPowermeter());
assertFalse(device.isHeatingThermostat());
@ -507,6 +520,7 @@ public class AVMFritzDeviceListModelTest {
assertFalse(device.isDectRepeater());
assertFalse(device.isSwitchableOutlet());
assertFalse(device.isTempSensor());
assertFalse(device.isHumiditySensor());
assertFalse(device.isPowermeter());
assertFalse(device.isHeatingThermostat());
@ -546,6 +560,7 @@ public class AVMFritzDeviceListModelTest {
assertFalse(group.isDectRepeater());
assertFalse(group.isSwitchableOutlet());
assertFalse(group.isTempSensor());
assertFalse(group.isHumiditySensor());
assertFalse(group.isPowermeter());
assertTrue(group.isHeatingThermostat());
@ -582,6 +597,7 @@ public class AVMFritzDeviceListModelTest {
assertFalse(group.isDectRepeater());
assertTrue(group.isSwitchableOutlet());
assertFalse(group.isTempSensor());
assertFalse(group.isHumiditySensor());
assertTrue(group.isPowermeter());
assertFalse(group.isHeatingThermostat());