diff --git a/bundles/org.openhab.binding.avmfritz/README.md b/bundles/org.openhab.binding.avmfritz/README.md index 0eacdf00399f5..306aca3aac661 100644 --- a/bundles/org.openhab.binding.avmfritz/README.md +++ b/bundles/org.openhab.binding.avmfritz/README.md @@ -266,6 +266,11 @@ val actions = getActions("avmfritz","avmfritz:Comet_DECT:1:aaaaaabbbbbb") actions.setBoostMode(300) ``` +For power meter devices like FRITZ!DECT 200 or FRITZ!Smart Energy 250 there are actions to enable / disable high refresh polling: `enablePowerMeterHighRefresh(long)` and `disablePowerMeterHighRefresh()`. +In general DECT devices submit their values every two minutes. +Whenever a user visits the detail page of a device in FRITZ!OS the values are requested more often - every ten seconds. +This action forces the high refresh interval of values by calling the related function on the FRITZ!Box interface. + ## Full Example demo.things: diff --git a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/AVMFritzBindingConstants.java b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/AVMFritzBindingConstants.java index bd2a8859e70c7..3686ffe296695 100644 --- a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/AVMFritzBindingConstants.java +++ b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/AVMFritzBindingConstants.java @@ -109,9 +109,10 @@ public class AVMFritzBindingConstants { public static final String CONFIG_AIN = "ain"; // List of all Properties + public static final String PROPERTY_DEVICE_ID = "deviceId"; public static final String PROPERTY_MASTER = "master"; public static final String PROPERTY_MEMBERS = "members"; - public static final String PRODUCT_NAME = "productName"; + public static final String PROPERTY_PRODUCT_NAME = "productName"; // List of all channel groups public static final String CHANNEL_GROUP_DEVICE = "device"; @@ -181,13 +182,15 @@ public class AVMFritzBindingConstants { public static final String MODE_AUTO = "AUTOMATIC"; public static final String MODE_MANUAL = "MANUAL"; public static final String MODE_VACATION = "VACATION"; - public static final String MODE_ON = "ON"; - public static final String MODE_OFF = "OFF"; - public static final String MODE_COMFORT = "COMFORT"; - public static final String MODE_ECO = "ECO"; - public static final String MODE_BOOST = "BOOST"; - public static final String MODE_WINDOW_OPEN = "WINDOW_OPEN"; - public static final String MODE_UNKNOWN = "UNKNOWN"; + public static final String HEATING_MODE_ON = "ON"; + public static final String HEATING_MODE_OFF = "OFF"; + public static final String HEATING_MODE_COMFORT = "COMFORT"; + public static final String HEATING_MODE_ECO = "ECO"; + public static final String HEATING_MODE_BOOST = "BOOST"; + public static final String HEATING_MODE_WINDOW_OPEN = "WINDOW_OPEN"; + public static final String HEATING_MODE_UNKNOWN = "UNKNOWN"; + + public static final String GET_ENERGY_STATS = "GET_ENERGY_STATS"; public static final Set SUPPORTED_LIGHTING_THING_TYPES = Set.of(DECT500_THING_TYPE, HAN_FUN_COLOR_BULB_THING_TYPE, HAN_FUN_DIMMABLE_BULB_THING_TYPE); @@ -198,10 +201,12 @@ public class AVMFritzBindingConstants { public static final Set SUPPORTED_HEATING_THING_TYPES = Set.of(DECT300_THING_TYPE, DECT302_THING_TYPE, DECT301_THING_TYPE, COMETDECT_THING_TYPE); + public static final Set SUPPORTED_POWER_METER_THING_TYPES = Set.of(DECT200_THING_TYPE, + DECT210_THING_TYPE); + public static final Set SUPPORTED_DEVICE_THING_TYPES_UIDS = Set.of(DECT100_THING_TYPE, - DECT200_THING_TYPE, DECT210_THING_TYPE, POWERLINE546E_THING_TYPE, HAN_FUN_CONTACT_THING_TYPE, - HAN_FUN_ON_OFF_THING_TYPE, HAN_FUN_BLINDS_THING_TYPE, HAN_FUN_SENSOR_THING_TYPE, HAN_FUN_HOST_THING_TYPE, - SMART_ENERGY_250_THING_TYPE); + POWERLINE546E_THING_TYPE, HAN_FUN_CONTACT_THING_TYPE, HAN_FUN_ON_OFF_THING_TYPE, HAN_FUN_BLINDS_THING_TYPE, + HAN_FUN_SENSOR_THING_TYPE, HAN_FUN_HOST_THING_TYPE, SMART_ENERGY_250_THING_TYPE); public static final Set SUPPORTED_GROUP_THING_TYPES_UIDS = Set.of(GROUP_HEATING_THING_TYPE, GROUP_SWITCH_THING_TYPE); @@ -209,10 +214,11 @@ public class AVMFritzBindingConstants { public static final Set SUPPORTED_BRIDGE_THING_TYPES_UIDS = Set.of(BRIDGE_THING_TYPE, POWERLINE546E_STANDALONE_THING_TYPE); - public static final Set SUPPORTED_THING_TYPES_UIDS = Stream.of(SUPPORTED_LIGHTING_THING_TYPES, - SUPPORTED_BUTTON_THING_TYPES_UIDS, SUPPORTED_HEATING_THING_TYPES, SUPPORTED_DEVICE_THING_TYPES_UIDS, - SUPPORTED_GROUP_THING_TYPES_UIDS, SUPPORTED_BRIDGE_THING_TYPES_UIDS).flatMap(Set::stream) - .collect(Collectors.toUnmodifiableSet()); + public static final Set SUPPORTED_THING_TYPES_UIDS = Stream + .of(SUPPORTED_LIGHTING_THING_TYPES, SUPPORTED_BUTTON_THING_TYPES_UIDS, SUPPORTED_HEATING_THING_TYPES, + SUPPORTED_POWER_METER_THING_TYPES, SUPPORTED_DEVICE_THING_TYPES_UIDS, + SUPPORTED_GROUP_THING_TYPES_UIDS, SUPPORTED_BRIDGE_THING_TYPES_UIDS) + .flatMap(Set::stream).collect(Collectors.toUnmodifiableSet()); // Lookup of new (alias) to old product names public static final Map ALIAS_PRODUCT_NAME_MAP = Map.of( // diff --git a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/AVMFritzHandlerFactory.java b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/AVMFritzHandlerFactory.java index 5e25b84979ad9..ca2e5f481487b 100644 --- a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/AVMFritzHandlerFactory.java +++ b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/AVMFritzHandlerFactory.java @@ -21,6 +21,7 @@ import org.openhab.binding.avmfritz.internal.handler.AVMFritzColorLightDeviceHandler; import org.openhab.binding.avmfritz.internal.handler.AVMFritzHeatingDeviceHandler; import org.openhab.binding.avmfritz.internal.handler.AVMFritzHeatingGroupHandler; +import org.openhab.binding.avmfritz.internal.handler.AVMFritzPowerMeterDeviceHandler; import org.openhab.binding.avmfritz.internal.handler.BoxHandler; import org.openhab.binding.avmfritz.internal.handler.DeviceHandler; import org.openhab.binding.avmfritz.internal.handler.GroupHandler; @@ -83,6 +84,8 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) { return new AVMFritzButtonHandler(thing); } else if (SUPPORTED_HEATING_THING_TYPES.contains(thingTypeUID)) { return new AVMFritzHeatingDeviceHandler(thing); + } else if (SUPPORTED_POWER_METER_THING_TYPES.contains(thingTypeUID)) { + return new AVMFritzPowerMeterDeviceHandler(thing); } else if (SUPPORTED_DEVICE_THING_TYPES_UIDS.contains(thingTypeUID)) { return new DeviceHandler(thing); } else if (GROUP_HEATING_THING_TYPE.equals(thingTypeUID)) { diff --git a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/actions/AVMFritzHeatingActions.java b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/actions/AVMFritzHeatingActions.java index 5179bb6c389d5..0728f304bb7ca 100644 --- a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/actions/AVMFritzHeatingActions.java +++ b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/actions/AVMFritzHeatingActions.java @@ -52,6 +52,7 @@ public void setBoostMode( if (duration == null) { throw new IllegalArgumentException("Cannot set Boost mode as 'duration' is null!"); } + validateDuration(duration.longValue()); actionsHandler.setBoostMode(duration.longValue()); } @@ -69,10 +70,17 @@ public void setWindowOpenMode( if (duration == null) { throw new IllegalArgumentException("Cannot set Window Open mode as 'duration' is null!"); } + validateDuration(duration.longValue()); actionsHandler.setWindowOpenMode(duration.longValue()); } public static void setWindowOpenMode(ThingActions actions, @Nullable Long duration) { ((AVMFritzHeatingActions) actions).setWindowOpenMode(duration); } + + private void validateDuration(long duration) { + if (duration < 0 || 86400 < duration) { + throw new IllegalArgumentException("Duration must not be less than zero or greater than 86400"); + } + } } diff --git a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/actions/AVMFritzPowerMeterActions.java b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/actions/AVMFritzPowerMeterActions.java new file mode 100644 index 0000000000000..cdc133fb5bc41 --- /dev/null +++ b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/actions/AVMFritzPowerMeterActions.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2010-2025 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.actions; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.openhab.binding.avmfritz.internal.handler.AVMFritzPowerMeterActionsHandler; +import org.openhab.core.automation.annotation.ActionInput; +import org.openhab.core.automation.annotation.RuleAction; +import org.openhab.core.thing.binding.ThingActions; +import org.openhab.core.thing.binding.ThingActionsScope; +import org.openhab.core.thing.binding.ThingHandler; + +/** + * The {@link AVMFritzPowerMeterActions} defines thing actions for power meter devices / groups of the avmfritz binding. + * + * @author Christoph Weitkamp - Initial contribution + */ +@ThingActionsScope(name = "avmfritz") +@NonNullByDefault +public class AVMFritzPowerMeterActions implements ThingActions { + + private @Nullable AVMFritzPowerMeterActionsHandler handler; + + @Override + public void setThingHandler(@Nullable ThingHandler handler) { + this.handler = (AVMFritzPowerMeterActionsHandler) handler; + } + + @Override + public @Nullable ThingHandler getThingHandler() { + return handler; + } + + @RuleAction(label = "@text/enablePowerMeterHighRefreshActionLabel", description = "@text/enablePowerMeterHighRefreshActionDescription") + public void enablePowerMeterHighRefresh( + @ActionInput(name = "Device Id", label = "@text/enablePowerMeterHighRefreshInputLabel", description = "@text/enablePowerMeterHighRefreshInputDescription", type = "java.lang.Long", required = true) @Nullable Long deviceId) { + AVMFritzPowerMeterActionsHandler actionsHandler = handler; + if (actionsHandler == null) { + throw new IllegalArgumentException("AVMFritzPowerMeterDeviceHandler ThingHandler is null!"); + } + if (deviceId == null) { + throw new IllegalArgumentException("Cannot enable power meter high refresh as 'deviceId' is null!"); + } + actionsHandler.enablePowerMeterHighRefresh(deviceId.longValue()); + } + + public static void enablePowerMeterHighRefresh(ThingActions actions, @Nullable Long deviceId) { + ((AVMFritzPowerMeterActions) actions).enablePowerMeterHighRefresh(deviceId); + } + + @RuleAction(label = "@text/disablePowerMeterHighRefreshActionLabel", description = "@text/disablePowerMeterHighRefreshActionDescription") + public void disablePowerMeterHighRefresh() { + AVMFritzPowerMeterActionsHandler actionsHandler = handler; + if (actionsHandler == null) { + throw new IllegalArgumentException("AVMFritzPowerMeterDeviceHandler ThingHandler is null!"); + } + actionsHandler.disablePowerMeterHighRefresh(); + } + + public static void disablePowerMeterHighRefresh(ThingActions actions) { + ((AVMFritzPowerMeterActions) actions).disablePowerMeterHighRefresh(); + } +} diff --git a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/discovery/AVMFritzDiscoveryService.java b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/discovery/AVMFritzDiscoveryService.java index 2394aee4337fc..60763a1c0438f 100644 --- a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/discovery/AVMFritzDiscoveryService.java +++ b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/discovery/AVMFritzDiscoveryService.java @@ -13,7 +13,6 @@ package org.openhab.binding.avmfritz.internal.discovery; import static org.openhab.binding.avmfritz.internal.AVMFritzBindingConstants.*; -import static org.openhab.core.thing.Thing.*; import java.util.HashMap; import java.util.Map; @@ -32,6 +31,7 @@ import org.openhab.core.config.discovery.DiscoveryService; import org.openhab.core.i18n.LocaleProvider; import org.openhab.core.i18n.TranslationProvider; +import org.openhab.core.thing.Thing; import org.openhab.core.thing.ThingTypeUID; import org.openhab.core.thing.ThingUID; import org.osgi.framework.Bundle; @@ -59,10 +59,12 @@ public class AVMFritzDiscoveryService extends AbstractThingHandlerDiscoveryServi @Activate public AVMFritzDiscoveryService(final @Reference LocaleProvider localeProvider, final @Reference TranslationProvider i18nProvider) { - super(AVMFritzBaseBridgeHandler.class, Stream - .of(SUPPORTED_LIGHTING_THING_TYPES, SUPPORTED_BUTTON_THING_TYPES_UIDS, SUPPORTED_HEATING_THING_TYPES, - SUPPORTED_DEVICE_THING_TYPES_UIDS, SUPPORTED_GROUP_THING_TYPES_UIDS) - .flatMap(Set::stream).collect(Collectors.toUnmodifiableSet()), 30); + super(AVMFritzBaseBridgeHandler.class, + Stream.of(SUPPORTED_LIGHTING_THING_TYPES, SUPPORTED_BUTTON_THING_TYPES_UIDS, + SUPPORTED_HEATING_THING_TYPES, SUPPORTED_POWER_METER_THING_TYPES, + SUPPORTED_DEVICE_THING_TYPES_UIDS, SUPPORTED_GROUP_THING_TYPES_UIDS).flatMap(Set::stream) + .collect(Collectors.toUnmodifiableSet()), + 30); this.localeProvider = localeProvider; this.i18nProvider = i18nProvider; this.bundle = FrameworkUtil.getBundle(AVMFritzDiscoveryService.class); @@ -119,10 +121,11 @@ private void onDeviceAddedInternal(ThingUID thingUID, AVMFritzBaseModel device) if (device.getPresent() == 1) { Map properties = new HashMap<>(); properties.put(CONFIG_AIN, device.getIdentifier()); - properties.put(PROPERTY_VENDOR, device.getManufacturer()); - properties.put(PRODUCT_NAME, device.getProductName()); - properties.put(PROPERTY_SERIAL_NUMBER, device.getIdentifier()); - properties.put(PROPERTY_FIRMWARE_VERSION, device.getFirmwareVersion()); + properties.put(PROPERTY_DEVICE_ID, device.getDeviceId()); + properties.put(Thing.PROPERTY_VENDOR, device.getManufacturer()); + properties.put(PROPERTY_PRODUCT_NAME, device.getProductName()); + properties.put(Thing.PROPERTY_SERIAL_NUMBER, device.getIdentifier()); + properties.put(Thing.PROPERTY_FIRMWARE_VERSION, device.getFirmwareVersion()); if (device instanceof GroupModel model && model.getGroupinfo() != null) { properties.put(PROPERTY_MASTER, model.getGroupinfo().getMasterdeviceid()); properties.put(PROPERTY_MEMBERS, model.getGroupinfo().getMembers()); diff --git a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/dto/AVMFritzBaseModel.java b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/dto/AVMFritzBaseModel.java index ad48527622314..98ba606049c22 100644 --- a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/dto/AVMFritzBaseModel.java +++ b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/dto/AVMFritzBaseModel.java @@ -106,7 +106,7 @@ public abstract class AVMFritzBaseModel implements BatteryModel { private @Nullable SimpleOnOffModel simpleOnOffUnit; @XmlElement(name = "powermeter") - private PowerMeterModel powermeterModel; + private PowerMeterModel powerMeterModel; @XmlElement(name = "hkr") private HeatingModel heatingModel; @@ -115,12 +115,12 @@ public abstract class AVMFritzBaseModel implements BatteryModel { return simpleOnOffUnit; } - public PowerMeterModel getPowermeter() { - return powermeterModel; + public PowerMeterModel getPowerMeter() { + return powerMeterModel; } - public void setPowermeter(PowerMeterModel powermeter) { - this.powermeterModel = powermeter; + public void setPowerMeter(PowerMeterModel powerMeter) { + this.powerMeterModel = powerMeter; } public HeatingModel getHkr() { @@ -179,7 +179,7 @@ public boolean isHumiditySensor() { return (bitmask & HUMIDITY_SENSOR_BIT) > 0; } - public boolean isPowermeter() { + public boolean isPowerMeter() { return (bitmask & POWERMETER_BIT) > 0; } @@ -256,7 +256,7 @@ public String toString() { .append(",isHANFUNAlarmSensor=").append(isHANFUNAlarmSensor()).append(",isButton=").append(isButton()) .append(",isSwitchableOutlet=").append(isSwitchableOutlet()).append(",isTemperatureSensor=") .append(isTemperatureSensor()).append(",isHumiditySensor=").append(isHumiditySensor()) - .append(",isPowermeter=").append(isPowermeter()).append(",isDectRepeater=").append(isDectRepeater()) + .append(",isPowermeter=").append(isPowerMeter()).append(",isDectRepeater=").append(isDectRepeater()) .append(",isHeatingThermostat=").append(isHeatingThermostat()).append(",hasMicrophone=") .append(hasMicrophone()).append(",isHANFUNUnit=").append(isHANFUNUnit()).append(",isHANFUNOnOff=") .append(isHANFUNOnOff()).append(",isDimmableLight=").append(isDimmableLight()).append(",isColorLight=") @@ -265,7 +265,7 @@ public String toString() { .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(getSimpleOnOffUnit()) - .append(",").append(getPowermeter()).append(",").append(getHkr()).append(",").toString(); + .append(",").append(getPowerMeter()).append(",").append(getHkr()).append(",").toString(); } public transient boolean isLinked; diff --git a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/dto/DeviceListModel.java b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/dto/DeviceListModel.java index 70eda0419ac09..01f7213f54ff5 100644 --- a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/dto/DeviceListModel.java +++ b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/dto/DeviceListModel.java @@ -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; @@ -98,7 +97,7 @@ public class DeviceListModel { public List getDevicelist() { if (devices == null) { - devices = Collections.emptyList(); + devices = List.of(); } return devices; } diff --git a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/dto/HeatingModel.java b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/dto/HeatingModel.java index 33be7d8fc1062..6aa2fe1cf84b2 100644 --- a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/dto/HeatingModel.java +++ b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/dto/HeatingModel.java @@ -111,21 +111,21 @@ public String getMode() { public String getRadiatorMode() { if (isOne(getWindowopenactiv())) { - return MODE_WINDOW_OPEN; + return HEATING_MODE_WINDOW_OPEN; } else if (isOne(getBoostactive()) || (tsoll != null && TEMP_FRITZ_MAX.compareTo(tsoll) == 0)) { - return MODE_BOOST; + return HEATING_MODE_BOOST; } else if (tsoll == null) { - return MODE_UNKNOWN; + return HEATING_MODE_UNKNOWN; } else if (TEMP_FRITZ_ON.compareTo(tsoll) == 0) { - return MODE_ON; + return HEATING_MODE_ON; } else if (TEMP_FRITZ_OFF.compareTo(tsoll) == 0) { - return MODE_OFF; + return HEATING_MODE_OFF; } else if (komfort != null && komfort.compareTo(tsoll) == 0) { - return MODE_COMFORT; + return HEATING_MODE_COMFORT; } else if (absenk != null && absenk.compareTo(tsoll) == 0) { - return MODE_ECO; + return HEATING_MODE_ECO; } else { - return MODE_ON; + return HEATING_MODE_ON; } } diff --git a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/dto/json/EnergyStats.java b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/dto/json/EnergyStats.java new file mode 100644 index 0000000000000..aa036b57ee671 --- /dev/null +++ b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/dto/json/EnergyStats.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2010-2025 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.json; + +import com.google.gson.annotations.SerializedName; + +/** + * + * @author Christoph Weitkamp - Initial contribution + */ +public class EnergyStats { + @SerializedName("DeviceConnectState") + public String deviceConnectState; + @SerializedName("VoltageStat") + public Values voltageStat; + @SerializedName("MM_Value_Amp") + public int mMValueAmp; + @SerializedName("sum_Year") + public int sumYear; + @SerializedName("sum_Day") + public int sumDay; + @SerializedName("MM_Value_Volt") + public int mMValueVolt; + @SerializedName("MM_Value_Power") + public int mMValuePower; + @SerializedName("tabType") + public String tabType; + @SerializedName("DeviceID") + public String deviceID; + @SerializedName("DeviceSwitchState") + public String deviceSwitchState; + @SerializedName("EnergyStat") + public Values energyStat; + @SerializedName("CurrentDateInSec") + public String currentDateInSec; + @SerializedName("sum_Month") + public int sumMonth; + @SerializedName("RequestResult") + public boolean requestResult; +} diff --git a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/dto/json/Values.java b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/dto/json/Values.java new file mode 100644 index 0000000000000..9c0e898dce7ea --- /dev/null +++ b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/dto/json/Values.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2010-2025 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.json; + +import java.util.List; + +import com.google.gson.annotations.SerializedName; + +/** + * + * @author Christoph Weitkamp - Initial contribution + */ +public class Values { + @SerializedName("ebene") + public int ebene; + @SerializedName("anzahl") + public int anzahl; + @SerializedName("values") + public List values; + @SerializedName("times_type") + public int timesType; + @SerializedName("ID") + public int id; + @SerializedName("datatimestamp") + public int datatimestamp; +} diff --git a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/dto/templates/DeviceListModel.java b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/dto/templates/DeviceListModel.java index 90a6328df8878..88914cc599d6b 100644 --- a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/dto/templates/DeviceListModel.java +++ b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/dto/templates/DeviceListModel.java @@ -12,7 +12,6 @@ */ package org.openhab.binding.avmfritz.internal.dto.templates; -import java.util.Collections; import java.util.List; import javax.xml.bind.annotation.XmlAccessType; @@ -34,7 +33,7 @@ public class DeviceListModel { public List getDevices() { if (devices == null) { - devices = Collections.emptyList(); + devices = List.of(); } return devices; } diff --git a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/dto/templates/TemplateListModel.java b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/dto/templates/TemplateListModel.java index 0d3e73662b287..047280c440a8d 100644 --- a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/dto/templates/TemplateListModel.java +++ b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/dto/templates/TemplateListModel.java @@ -12,7 +12,6 @@ */ package org.openhab.binding.avmfritz.internal.dto.templates; -import java.util.Collections; import java.util.List; import javax.xml.bind.annotation.XmlAccessType; @@ -40,7 +39,7 @@ public class TemplateListModel { public List getTemplates() { if (templates == null) { - templates = Collections.emptyList(); + templates = List.of(); } return templates; } diff --git a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/handler/AVMFritzBaseBridgeHandler.java b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/handler/AVMFritzBaseBridgeHandler.java index 885a88681c553..14e6b7d442136 100644 --- a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/handler/AVMFritzBaseBridgeHandler.java +++ b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/handler/AVMFritzBaseBridgeHandler.java @@ -304,6 +304,7 @@ public void onDeviceListAdded(List deviceList) { if (thingTypeUID != null && (SUPPORTED_BUTTON_THING_TYPES_UIDS.contains(thingTypeUID) || SUPPORTED_LIGHTING_THING_TYPES.contains(thingTypeUID) || SUPPORTED_HEATING_THING_TYPES.contains(thingTypeUID) + || SUPPORTED_POWER_METER_THING_TYPES.contains(thingTypeUID) || SUPPORTED_DEVICE_THING_TYPES_UIDS.contains(thingTypeUID))) { return new ThingUID(thingTypeUID, bridgeUID, thingName); } else if (device.isHeatingThermostat()) { diff --git a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/handler/AVMFritzBaseThingHandler.java b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/handler/AVMFritzBaseThingHandler.java index 34fe57f3dab57..32d2f3d890c7a 100644 --- a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/handler/AVMFritzBaseThingHandler.java +++ b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/handler/AVMFritzBaseThingHandler.java @@ -136,8 +136,8 @@ public void onDeviceUpdated(ThingUID thingUID, AVMFritzBaseModel device) { updateProperties(device, editProperties()); - if (device.isPowermeter()) { - updatePowermeter(device.getPowermeter()); + if (device.isPowerMeter()) { + updatePowerMeter(device.getPowerMeter()); } if (device.isSwitchableOutlet()) { updateSwitchableOutlet(device.getSwitch()); @@ -318,7 +318,7 @@ private void updateSwitchableOutlet(@Nullable SwitchModel switchModel) { } } - private void updatePowermeter(@Nullable PowerMeterModel powerMeterModel) { + private void updatePowerMeter(@Nullable PowerMeterModel powerMeterModel) { if (powerMeterModel != null) { updateThingChannelState(CHANNEL_ENERGY, new QuantityType<>(powerMeterModel.getEnergy(), Units.WATT_HOUR)); updateThingChannelState(CHANNEL_POWER, new QuantityType<>(powerMeterModel.getPower(), Units.WATT)); @@ -334,6 +334,7 @@ private void updatePowermeter(@Nullable PowerMeterModel powerMeterModel) { */ protected void updateProperties(AVMFritzBaseModel device, Map editProperties) { editProperties.put(Thing.PROPERTY_FIRMWARE_VERSION, device.getFirmwareVersion()); + editProperties.put(PROPERTY_DEVICE_ID, device.getDeviceId()); updateProperties(editProperties); } @@ -552,23 +553,23 @@ public void handleCommand(ChannelUID channelUID, Command command) { BigDecimal targetTemperature = null; if (command instanceof StringType) { switch (command.toString()) { - case MODE_ON: + case HEATING_MODE_ON: targetTemperature = TEMP_FRITZ_ON; break; - case MODE_OFF: + case HEATING_MODE_OFF: targetTemperature = TEMP_FRITZ_OFF; break; - case MODE_COMFORT: + case HEATING_MODE_COMFORT: targetTemperature = currentDevice.getHkr().getKomfort(); break; - case MODE_ECO: + case HEATING_MODE_ECO: targetTemperature = currentDevice.getHkr().getAbsenk(); break; - case MODE_BOOST: + case HEATING_MODE_BOOST: targetTemperature = TEMP_FRITZ_MAX; break; - case MODE_UNKNOWN: - case MODE_WINDOW_OPEN: + case HEATING_MODE_UNKNOWN: + case HEATING_MODE_WINDOW_OPEN: logger.debug("Command '{}' is a read-only command for channel {}.", command, channelId); break; } @@ -609,9 +610,9 @@ public void handleCommand(ChannelUID channelUID, Command command) { * Handles a command for a given action. * * @param action - * @param duration + * @param param */ - protected void handleAction(String action, long duration) { + protected void handleAction(String action, long param) { FritzAhaWebInterface fritzBox = getWebInterface(); if (fritzBox == null) { logger.debug("Cannot handle action '{}' because connection is missing", action); @@ -622,17 +623,15 @@ protected void handleAction(String action, long duration) { logger.debug("Cannot handle action '{}' because AIN is missing", action); return; } - if (duration < 0 || 86400 < duration) { - throw new IllegalArgumentException("Duration must not be less than zero or greater than 86400"); - } switch (action) { - case MODE_BOOST: - fritzBox.setBoostMode(ain, - duration > 0 ? ZonedDateTime.now().plusSeconds(duration).toEpochSecond() : 0); + case HEATING_MODE_BOOST: + fritzBox.setBoostMode(ain, param > 0 ? ZonedDateTime.now().plusSeconds(param).toEpochSecond() : 0); + break; + case HEATING_MODE_WINDOW_OPEN: + fritzBox.setWindowOpenMode(ain, param > 0 ? ZonedDateTime.now().plusSeconds(param).toEpochSecond() : 0); break; - case MODE_WINDOW_OPEN: - fritzBox.setWindowOpenMode(ain, - duration > 0 ? ZonedDateTime.now().plusSeconds(duration).toEpochSecond() : 0); + case GET_ENERGY_STATS: + fritzBox.getEnergyStats((AVMFritzPowerMeterDeviceHandler) this, param); break; default: logger.debug("Received unknown action '{}'", action); diff --git a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/handler/AVMFritzHeatingDeviceHandler.java b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/handler/AVMFritzHeatingDeviceHandler.java index c395f7b9f2eec..7c07d4eda2ce5 100644 --- a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/handler/AVMFritzHeatingDeviceHandler.java +++ b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/handler/AVMFritzHeatingDeviceHandler.java @@ -31,11 +31,11 @@ public AVMFritzHeatingDeviceHandler(Thing thing) { @Override public void setBoostMode(long duration) { - handleAction(MODE_BOOST, duration); + handleAction(HEATING_MODE_BOOST, duration); } @Override public void setWindowOpenMode(long duration) { - handleAction(MODE_WINDOW_OPEN, duration); + handleAction(HEATING_MODE_WINDOW_OPEN, duration); } } diff --git a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/handler/AVMFritzHeatingGroupHandler.java b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/handler/AVMFritzHeatingGroupHandler.java index 0e2fa45b3bccb..0c42d90eb581e 100644 --- a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/handler/AVMFritzHeatingGroupHandler.java +++ b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/handler/AVMFritzHeatingGroupHandler.java @@ -31,11 +31,11 @@ public AVMFritzHeatingGroupHandler(Thing thing) { @Override public void setBoostMode(long duration) { - handleAction(MODE_BOOST, duration); + handleAction(HEATING_MODE_BOOST, duration); } @Override public void setWindowOpenMode(long duration) { - handleAction(MODE_WINDOW_OPEN, duration); + handleAction(HEATING_MODE_WINDOW_OPEN, duration); } } diff --git a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/handler/AVMFritzPowerMeterActionsHandler.java b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/handler/AVMFritzPowerMeterActionsHandler.java new file mode 100644 index 0000000000000..689c30caf7319 --- /dev/null +++ b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/handler/AVMFritzPowerMeterActionsHandler.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2010-2025 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.handler; + +import java.util.Collection; +import java.util.Set; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.binding.avmfritz.internal.actions.AVMFritzPowerMeterActions; +import org.openhab.core.thing.binding.ThingHandler; +import org.openhab.core.thing.binding.ThingHandlerService; + +/** + * The {@link AVMFritzPowerMeterActionsHandler} defines interface handlers to handle power meter thing actions. + * + * @author Christoph Weitkamp - Initial contribution + */ +@NonNullByDefault +public interface AVMFritzPowerMeterActionsHandler extends ThingHandler { + + @Override + default Collection> getServices() { + return Set.of(AVMFritzPowerMeterActions.class); + } + + /** + * Enables high refresh polling for this power meter. + * + * @param deviceId Id of the device. + */ + void enablePowerMeterHighRefresh(long deviceId); + + /** + * Disables high refresh polling for this power meter. + */ + void disablePowerMeterHighRefresh(); +} diff --git a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/handler/AVMFritzPowerMeterDeviceHandler.java b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/handler/AVMFritzPowerMeterDeviceHandler.java new file mode 100644 index 0000000000000..96392756b3c0b --- /dev/null +++ b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/handler/AVMFritzPowerMeterDeviceHandler.java @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2010-2025 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.handler; + +import static org.openhab.binding.avmfritz.internal.AVMFritzBindingConstants.*; + +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.openhab.binding.avmfritz.internal.dto.PowerMeterModel; +import org.openhab.binding.avmfritz.internal.dto.json.EnergyStats; +import org.openhab.core.library.types.QuantityType; +import org.openhab.core.library.unit.Units; +import org.openhab.core.thing.Thing; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; +import com.google.gson.JsonSyntaxException; + +/** + * Handler for a FRITZ! power meter. Handles commands, which are sent to one of the channels. + * + * @author Christoph Weitkamp - Initial contribution + */ +@NonNullByDefault +public class AVMFritzPowerMeterDeviceHandler extends DeviceHandler implements AVMFritzPowerMeterActionsHandler { + + private final Logger logger = LoggerFactory.getLogger(AVMFritzPowerMeterDeviceHandler.class); + + private final Gson gson = new Gson(); + + /** + * Schedule for polling + */ + private @Nullable ScheduledFuture pollingJob; + + private @Nullable Long deviceId; + + /** + * Constructor + * + * @param thing Thing object representing a FRITZ! device + */ + public AVMFritzPowerMeterDeviceHandler(Thing thing) { + super(thing); + } + + @Override + public void dispose() { + stopPolling(); + super.dispose(); + } + + @Override + public void enablePowerMeterHighRefresh(long deviceId) { + // TODO use Thing property "deviceId" instead of passing an argument + this.deviceId = deviceId; + startPolling(deviceId); + } + + @Override + public void disablePowerMeterHighRefresh() { + stopPolling(); + } + + public void onEnergyStatsUpdated(String response) { + try { + EnergyStats energyStats = gson.fromJson(response, EnergyStats.class); + if (energyStats != null) { + updateThingChannelState(CHANNEL_POWER, new QuantityType<>( + energyStats.mMValuePower * PowerMeterModel.POWER_FACTOR.doubleValue(), Units.WATT)); + updateThingChannelState(CHANNEL_VOLTAGE, new QuantityType<>( + energyStats.mMValueVolt * PowerMeterModel.VOLTAGE_FACTOR.doubleValue(), Units.VOLT)); + } + } catch (JsonSyntaxException e) { + logger.debug("Failed to parse JSON: {}", e.getMessage()); + } + } + + /** + * Start the polling. + */ + private void startPolling(long deviceId) { + ScheduledFuture localPollingJob = pollingJob; + if (localPollingJob == null || localPollingJob.isCancelled()) { + long pollingInterval = 10; + logger.debug("Start polling job for device '{}' at interval {}s", deviceId, pollingInterval); + pollingJob = scheduler.scheduleWithFixedDelay(() -> { + handleAction(GET_ENERGY_STATS, deviceId); + }, 0, pollingInterval, TimeUnit.SECONDS); + } + } + + /** + * Stops the polling. + */ + private void stopPolling() { + ScheduledFuture localPollingJob = pollingJob; + if (localPollingJob != null && !localPollingJob.isCancelled()) { + logger.debug("Stop polling job for device '{}'", deviceId); + localPollingJob.cancel(true); + pollingJob = null; + deviceId = null; + } + } +} diff --git a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/handler/Powerline546EHandler.java b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/handler/Powerline546EHandler.java index a4341ef741ebb..bc96126cb4fd9 100644 --- a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/handler/Powerline546EHandler.java +++ b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/handler/Powerline546EHandler.java @@ -127,8 +127,8 @@ public void onDeviceUpdated(ThingUID thingUID, AVMFritzBaseModel device) { updateProperties(device); - if (device.isPowermeter()) { - updatePowermeter(device.getPowermeter()); + if (device.isPowerMeter()) { + updatePowermeter(device.getPowerMeter()); } if (device.isSwitchableOutlet()) { updateSwitchableOutlet(device.getSwitch()); diff --git a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/hardware/FritzAhaWebInterface.java b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/hardware/FritzAhaWebInterface.java index 97b98f5e6f20f..cfeb70cf64bfc 100644 --- a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/hardware/FritzAhaWebInterface.java +++ b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/hardware/FritzAhaWebInterface.java @@ -30,8 +30,10 @@ import org.eclipse.jetty.http.HttpMethod; import org.openhab.binding.avmfritz.internal.config.AVMFritzBoxConfiguration; import org.openhab.binding.avmfritz.internal.handler.AVMFritzBaseBridgeHandler; +import org.openhab.binding.avmfritz.internal.handler.AVMFritzPowerMeterDeviceHandler; 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.FritzAhaGetEnergyStatsCallback; 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.FritzAhaSetColorCallback; @@ -302,6 +304,11 @@ public FritzAhaContentExchange applyTemplate(String ain) { return asyncGet(callback); } + public FritzAhaContentExchange getEnergyStats(AVMFritzPowerMeterDeviceHandler handler, long deviceId) { + FritzAhaGetEnergyStatsCallback callback = new FritzAhaGetEnergyStatsCallback(this, handler, deviceId); + return asyncGet(callback); + } + public FritzAhaContentExchange setSwitch(String ain, boolean switchOn) { FritzAhaSetSwitchCallback callback = new FritzAhaSetSwitchCallback(this, ain, switchOn); return asyncGet(callback); diff --git a/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/hardware/callbacks/FritzAhaGetEnergyStatsCallback.java b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/hardware/callbacks/FritzAhaGetEnergyStatsCallback.java new file mode 100644 index 0000000000000..b4b52ff172cb3 --- /dev/null +++ b/bundles/org.openhab.binding.avmfritz/src/main/java/org/openhab/binding/avmfritz/internal/hardware/callbacks/FritzAhaGetEnergyStatsCallback.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2010-2025 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.handler.AVMFritzPowerMeterDeviceHandler; +import org.openhab.binding.avmfritz.internal.hardware.FritzAhaWebInterface; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Callback implementation for updating power meter readings + * + * @author Christoph Weitkamp - Initial contribution + */ +@NonNullByDefault +public class FritzAhaGetEnergyStatsCallback extends FritzAhaReauthCallback { + + private static final String WEBSERVICE_PATH = "net/home_auto_query.lua"; + + private final Logger logger = LoggerFactory.getLogger(FritzAhaGetEnergyStatsCallback.class); + + private final AVMFritzPowerMeterDeviceHandler handler; + + private final long deviceId; + + /** + * Constructor + * + * @param webIface Interface to FRITZ!Box + * @param deviceId ID of the device that should be updated + */ + public FritzAhaGetEnergyStatsCallback(FritzAhaWebInterface webIface, AVMFritzPowerMeterDeviceHandler handler, + long deviceId) { + super(WEBSERVICE_PATH, "no_sidrenew=1&command=EnergyStats_10&useajax=1&xhr=1&id=" + deviceId, webIface, GET, 1); + this.handler = handler; + this.deviceId = deviceId; + } + + @Override + public void execute(int status, String response) { + super.execute(status, response); + logger.debug("Received EnergyStats response '{}' for item '{}'", response, deviceId); + if (isValidRequest()) { + handler.onEnergyStatsUpdated(response); + } + } +} diff --git a/bundles/org.openhab.binding.avmfritz/src/main/resources/OH-INF/i18n/avmfritz.properties b/bundles/org.openhab.binding.avmfritz/src/main/resources/OH-INF/i18n/avmfritz.properties index 5e387428073bc..3553dd0e86c95 100644 --- a/bundles/org.openhab.binding.avmfritz/src/main/resources/OH-INF/i18n/avmfritz.properties +++ b/bundles/org.openhab.binding.avmfritz/src/main/resources/OH-INF/i18n/avmfritz.properties @@ -235,6 +235,13 @@ setWindowOpenModeActionDescription = Activates the Window Open mode of the heati setWindowOpenModeDurationInputLabel = Duration setWindowOpenModeDurationInputDescription = Duration in seconds, min. 1, max. 86400, 0 for deactivation. +enablePowerMeterHighRefreshActionLabel = enable high refresh polling +enablePowerMeterHighRefreshActionDescription = Enables high refresh polling for the given device for every 10 seconds. +enablePowerMeterHighRefreshInputLabel = Device Id +enablePowerMeterHighRefreshInputDescription = The id of the device. +disablePowerMeterHighRefreshActionLabel = disable high refresh polling +disablePowerMeterHighRefreshActionDescription = Disable high refresh polling for the device. + # host thing label host.thing.label = Host Thing for diff --git a/bundles/org.openhab.binding.avmfritz/src/test/java/org/openhab/binding/avmfritz/internal/actions/AVMFritzHeatingActionsTest.java b/bundles/org.openhab.binding.avmfritz/src/test/java/org/openhab/binding/avmfritz/internal/actions/AVMFritzHeatingActionsTest.java index fa404c62fb490..86a76210c6c93 100644 --- a/bundles/org.openhab.binding.avmfritz/src/test/java/org/openhab/binding/avmfritz/internal/actions/AVMFritzHeatingActionsTest.java +++ b/bundles/org.openhab.binding.avmfritz/src/test/java/org/openhab/binding/avmfritz/internal/actions/AVMFritzHeatingActionsTest.java @@ -78,6 +78,20 @@ public void testSetBoostMode() { AVMFritzHeatingActions.setBoostMode(heatingActions, Long.valueOf(5L)); } + @Test + public void testSetBoostModeThrowsIllegalArgumentExceptionIfDurationIsLessThanZero() { + heatingActions.setThingHandler(heatingActionsHandlerMock); + assertThrows(IllegalArgumentException.class, + () -> AVMFritzHeatingActions.setBoostMode(heatingActions, Long.valueOf(-5L))); + } + + @Test + public void testSetBoostModeThrowsIllegalArgumentExceptionIfDurationIsTooBig() { + heatingActions.setThingHandler(heatingActionsHandlerMock); + assertThrows(IllegalArgumentException.class, + () -> AVMFritzHeatingActions.setBoostMode(heatingActions, Long.valueOf(86500L))); + } + @Test public void testSetWindowOpenModeThingActionsIsNotAVMFritzHeatingActions() { assertThrows(ClassCastException.class, @@ -102,4 +116,18 @@ public void testSetWindowOpenMode() { heatingActions.setThingHandler(heatingActionsHandlerMock); AVMFritzHeatingActions.setWindowOpenMode(heatingActions, Long.valueOf(5L)); } + + @Test + public void testSetWindowOpenModeThrowsIllegalArgumentExceptionIfDurationIsLessThanZero() { + heatingActions.setThingHandler(heatingActionsHandlerMock); + assertThrows(IllegalArgumentException.class, + () -> AVMFritzHeatingActions.setWindowOpenMode(heatingActions, Long.valueOf(-5L))); + } + + @Test + public void testSetWindowOpenModeThrowsIllegalArgumentExceptionIfDurationIsTooBig() { + heatingActions.setThingHandler(heatingActionsHandlerMock); + assertThrows(IllegalArgumentException.class, + () -> AVMFritzHeatingActions.setWindowOpenMode(heatingActions, Long.valueOf(86500L))); + } } diff --git a/bundles/org.openhab.binding.avmfritz/src/test/java/org/openhab/binding/avmfritz/internal/actions/AVMFritzPowerMeterActionsTest.java b/bundles/org.openhab.binding.avmfritz/src/test/java/org/openhab/binding/avmfritz/internal/actions/AVMFritzPowerMeterActionsTest.java new file mode 100644 index 0000000000000..814b176aa6d3c --- /dev/null +++ b/bundles/org.openhab.binding.avmfritz/src/test/java/org/openhab/binding/avmfritz/internal/actions/AVMFritzPowerMeterActionsTest.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2010-2025 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.actions; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.openhab.binding.avmfritz.internal.handler.AVMFritzPowerMeterActionsHandler; +import org.openhab.core.thing.binding.ThingActions; +import org.openhab.core.thing.binding.ThingHandler; + +/** + * Unit tests for {@link AVMFritzPowerMeterActions}. + * + * @author Christoph Weitkamp - Initial contribution + */ +@ExtendWith(MockitoExtension.class) +@NonNullByDefault +public class AVMFritzPowerMeterActionsTest { + + private final ThingActions thingActionsStub = new ThingActions() { + @Override + public void setThingHandler(ThingHandler handler) { + } + + @Override + public @Nullable ThingHandler getThingHandler() { + return null; + } + }; + + private @Mock @NonNullByDefault({}) AVMFritzPowerMeterActionsHandler powerMeterActionsHandlerMock; + + private @NonNullByDefault({}) AVMFritzPowerMeterActions powerMeterActions; + + @BeforeEach + public void setUp() { + powerMeterActions = new AVMFritzPowerMeterActions(); + } + + @Test + public void testEnablePowerMeterHighRefreshThingActionsIsNotAVMFritzPowerMeterActions() { + assertThrows(ClassCastException.class, + () -> AVMFritzPowerMeterActions.enablePowerMeterHighRefresh(thingActionsStub, Long.valueOf(5L))); + } + + @Test + public void testEnablePowerMeterHighRefreshThingHandlerIsNull() { + assertThrows(IllegalArgumentException.class, + () -> AVMFritzPowerMeterActions.enablePowerMeterHighRefresh(powerMeterActions, Long.valueOf(5L))); + } + + @Test + public void testEnablePowerMeterHighRefreshDurationNull() { + powerMeterActions.setThingHandler(powerMeterActionsHandlerMock); + assertThrows(IllegalArgumentException.class, + () -> AVMFritzPowerMeterActions.enablePowerMeterHighRefresh(powerMeterActions, null)); + } + + @Test + public void testEnablePowerMeterHighRefresh() { + powerMeterActions.setThingHandler(powerMeterActionsHandlerMock); + AVMFritzPowerMeterActions.enablePowerMeterHighRefresh(powerMeterActions, Long.valueOf(5L)); + } + + @Test + public void testDisablePowerMeterHighRefreshThingActionsIsNotAVMFritzPowerMeterActions() { + assertThrows(ClassCastException.class, + () -> AVMFritzPowerMeterActions.disablePowerMeterHighRefresh(thingActionsStub)); + } + + @Test + public void testDisablePowerMeterHighRefreshThingHandlerIsNull() { + assertThrows(IllegalArgumentException.class, + () -> AVMFritzPowerMeterActions.disablePowerMeterHighRefresh(powerMeterActions)); + } + + @Test + public void testDisablePowerMeterHighRefresh() { + powerMeterActions.setThingHandler(powerMeterActionsHandlerMock); + AVMFritzPowerMeterActions.disablePowerMeterHighRefresh(powerMeterActions); + } +} diff --git a/bundles/org.openhab.binding.avmfritz/src/test/java/org/openhab/binding/avmfritz/internal/dto/AVMFritzDeviceListModelTest.java b/bundles/org.openhab.binding.avmfritz/src/test/java/org/openhab/binding/avmfritz/internal/dto/AVMFritzDeviceListModelTest.java index 9e56f52ed30a3..f962f327dd1ef 100644 --- a/bundles/org.openhab.binding.avmfritz/src/test/java/org/openhab/binding/avmfritz/internal/dto/AVMFritzDeviceListModelTest.java +++ b/bundles/org.openhab.binding.avmfritz/src/test/java/org/openhab/binding/avmfritz/internal/dto/AVMFritzDeviceListModelTest.java @@ -193,7 +193,7 @@ public void validateDECTRepeater100Model() { assertFalse(device.isSwitchableOutlet()); assertTrue(device.isTemperatureSensor()); assertFalse(device.isHumiditySensor()); - assertFalse(device.isPowermeter()); + assertFalse(device.isPowerMeter()); assertFalse(device.isHeatingThermostat()); assertFalse(device.isHANFUNBlinds()); @@ -203,7 +203,7 @@ public void validateDECTRepeater100Model() { assertEquals(new BigDecimal("23.0"), device.getTemperature().getCelsius()); assertEquals(new BigDecimal("0.0"), device.getTemperature().getOffset()); - assertNull(device.getPowermeter()); + assertNull(device.getPowerMeter()); assertNull(device.getHkr()); @@ -230,7 +230,7 @@ public void validateDECT200Model() { assertFalse(device.isHANFUNAlarmSensor()); assertFalse(device.isButton()); assertFalse(device.isHeatingThermostat()); - assertTrue(device.isPowermeter()); + assertTrue(device.isPowerMeter()); assertTrue(device.isTemperatureSensor()); assertTrue(device.isSwitchableOutlet()); assertFalse(device.isDectRepeater()); @@ -250,7 +250,7 @@ public void validateDECT200Model() { assertEquals(new BigDecimal("25.5"), device.getTemperature().getCelsius()); assertEquals(new BigDecimal("0.0"), device.getTemperature().getOffset()); - validatePowerMeter(device.getPowermeter()); + validatePowerMeter(device.getPowerMeter()); assertNull(device.getHkr()); @@ -277,7 +277,7 @@ public void validateDECT210Model() { assertFalse(device.isHANFUNAlarmSensor()); assertFalse(device.isButton()); assertFalse(device.isHeatingThermostat()); - assertTrue(device.isPowermeter()); + assertTrue(device.isPowerMeter()); assertTrue(device.isTemperatureSensor()); assertTrue(device.isSwitchableOutlet()); assertFalse(device.isDectRepeater()); @@ -297,7 +297,7 @@ public void validateDECT210Model() { assertEquals(new BigDecimal("25.5"), device.getTemperature().getCelsius()); assertEquals(new BigDecimal("0.0"), device.getTemperature().getOffset()); - validatePowerMeter(device.getPowermeter()); + validatePowerMeter(device.getPowerMeter()); assertNull(device.getHkr()); @@ -319,7 +319,7 @@ public void validateSmartEnergy250() { assertEquals(1, device.getPresent()); assertEquals("FRITZ!Smart Energy 250 #8", device.getName()); - assertTrue(device.isPowermeter()); + assertTrue(device.isPowerMeter()); assertFalse(device.isHANFUNButton()); assertFalse(device.isHANFUNAlarmSensor()); @@ -337,7 +337,7 @@ public void validateSmartEnergy250() { assertEquals(new BigDecimal("90"), device.getBattery()); assertEquals(BatteryModel.BATTERY_OFF, device.getBatterylow()); - PowerMeterModel powerMeter = device.getPowermeter(); + PowerMeterModel powerMeter = device.getPowerMeter(); assertNotNull(powerMeter); assertEquals(new BigDecimal("0.000"), powerMeter.getVoltage()); assertEquals(new BigDecimal("532.000"), powerMeter.getPower()); @@ -367,7 +367,7 @@ public void validateDECT300Model() { assertFalse(device.isSwitchableOutlet()); assertTrue(device.isTemperatureSensor()); assertFalse(device.isHumiditySensor()); - assertFalse(device.isPowermeter()); + assertFalse(device.isPowerMeter()); assertTrue(device.isHeatingThermostat()); assertFalse(device.isHANFUNBlinds()); @@ -377,7 +377,7 @@ public void validateDECT300Model() { assertEquals(new BigDecimal("22.0"), device.getTemperature().getCelsius()); assertEquals(new BigDecimal("-1.0"), device.getTemperature().getOffset()); - assertNull(device.getPowermeter()); + assertNull(device.getPowerMeter()); validateHeatingModel(device.getHkr()); } @@ -405,7 +405,7 @@ public void validateDECT301Model() { assertFalse(device.isSwitchableOutlet()); assertTrue(device.isTemperatureSensor()); assertFalse(device.isHumiditySensor()); - assertFalse(device.isPowermeter()); + assertFalse(device.isPowerMeter()); assertTrue(device.isHeatingThermostat()); assertFalse(device.isHANFUNBlinds()); @@ -415,7 +415,7 @@ public void validateDECT301Model() { assertEquals(new BigDecimal("22.0"), device.getTemperature().getCelsius()); assertEquals(new BigDecimal("-1.0"), device.getTemperature().getOffset()); - assertNull(device.getPowermeter()); + assertNull(device.getPowerMeter()); validateHeatingModel(device.getHkr()); } @@ -443,7 +443,7 @@ public void validateCometDECTModel() { assertFalse(device.isSwitchableOutlet()); assertTrue(device.isTemperatureSensor()); assertFalse(device.isHumiditySensor()); - assertFalse(device.isPowermeter()); + assertFalse(device.isPowerMeter()); assertTrue(device.isHeatingThermostat()); assertFalse(device.isHANFUNBlinds()); @@ -453,7 +453,7 @@ public void validateCometDECTModel() { assertEquals(new BigDecimal("22.0"), device.getTemperature().getCelsius()); assertEquals(new BigDecimal("-1.0"), device.getTemperature().getOffset()); - assertNull(device.getPowermeter()); + assertNull(device.getPowerMeter()); validateHeatingModel(device.getHkr()); } @@ -481,7 +481,7 @@ public void validateDECT400Model() { assertFalse(device.isSwitchableOutlet()); assertFalse(device.isTemperatureSensor()); assertFalse(device.isHumiditySensor()); - assertFalse(device.isPowermeter()); + assertFalse(device.isPowerMeter()); assertFalse(device.isHeatingThermostat()); assertFalse(device.isHANFUNBlinds()); @@ -500,7 +500,7 @@ public void validateDECT400Model() { assertNull(device.getTemperature()); - assertNull(device.getPowermeter()); + assertNull(device.getPowerMeter()); assertNull(device.getHkr()); @@ -530,7 +530,7 @@ public void validateDECT440Model() { assertFalse(device.isSwitchableOutlet()); assertTrue(device.isTemperatureSensor()); assertTrue(device.isHumiditySensor()); - assertFalse(device.isPowermeter()); + assertFalse(device.isPowerMeter()); assertFalse(device.isHeatingThermostat()); assertFalse(device.isHANFUNBlinds()); @@ -570,7 +570,7 @@ public void validateDECT440Model() { assertNotNull(device.getHumidity()); assertEquals(new BigDecimal("43"), device.getHumidity().getRelativeHumidity()); - assertNull(device.getPowermeter()); + assertNull(device.getPowerMeter()); assertNull(device.getHkr()); @@ -600,7 +600,7 @@ public void validatePowerline546EModel() { assertTrue(device.isSwitchableOutlet()); assertFalse(device.isTemperatureSensor()); assertFalse(device.isHumiditySensor()); - assertTrue(device.isPowermeter()); + assertTrue(device.isPowerMeter()); assertFalse(device.isHeatingThermostat()); assertFalse(device.isHANFUNBlinds()); @@ -612,7 +612,7 @@ public void validatePowerline546EModel() { assertNull(device.getTemperature()); - validatePowerMeter(device.getPowermeter()); + validatePowerMeter(device.getPowerMeter()); assertNull(device.getHkr()); @@ -642,7 +642,7 @@ public void validateHANFUNContactModel() { assertFalse(device.isSwitchableOutlet()); assertFalse(device.isTemperatureSensor()); assertFalse(device.isHumiditySensor()); - assertFalse(device.isPowermeter()); + assertFalse(device.isPowerMeter()); assertFalse(device.isHeatingThermostat()); assertFalse(device.isHANFUNBlinds()); @@ -655,7 +655,7 @@ public void validateHANFUNContactModel() { assertNull(device.getTemperature()); - assertNull(device.getPowermeter()); + assertNull(device.getPowerMeter()); assertNull(device.getHkr()); @@ -685,7 +685,7 @@ public void validateHANFUNSwitchModel() { assertFalse(device.isSwitchableOutlet()); assertFalse(device.isTemperatureSensor()); assertFalse(device.isHumiditySensor()); - assertFalse(device.isPowermeter()); + assertFalse(device.isPowerMeter()); assertFalse(device.isHeatingThermostat()); assertFalse(device.isHANFUNBlinds()); @@ -698,7 +698,7 @@ public void validateHANFUNSwitchModel() { assertNull(device.getTemperature()); - assertNull(device.getPowermeter()); + assertNull(device.getPowerMeter()); assertNull(device.getHkr()); @@ -728,7 +728,7 @@ public void validateHANFUNBlindModel() { assertFalse(device.isSwitchableOutlet()); assertFalse(device.isTemperatureSensor()); assertFalse(device.isHumiditySensor()); - assertFalse(device.isPowermeter()); + assertFalse(device.isPowerMeter()); assertFalse(device.isDectRepeater()); assertFalse(device.isHeatingThermostat()); assertFalse(device.hasMicrophone()); @@ -747,7 +747,7 @@ public void validateHANFUNBlindModel() { assertNull(device.getTemperature()); - assertNull(device.getPowermeter()); + assertNull(device.getPowerMeter()); assertNull(device.getHkr()); @@ -780,7 +780,7 @@ public void validateHANFUNColorLightModel() { assertFalse(device.isSwitchableOutlet()); assertFalse(device.isTemperatureSensor()); assertFalse(device.isHumiditySensor()); - assertFalse(device.isPowermeter()); + assertFalse(device.isPowerMeter()); assertFalse(device.isDectRepeater()); assertFalse(device.isHeatingThermostat()); assertFalse(device.hasMicrophone()); @@ -798,7 +798,7 @@ public void validateHANFUNColorLightModel() { assertNull(device.getTemperature()); - assertNull(device.getPowermeter()); + assertNull(device.getPowerMeter()); assertNull(device.getHkr()); @@ -839,7 +839,7 @@ public void validateHANFUNDimmableLightModel() { assertFalse(device.isSwitchableOutlet()); assertFalse(device.isTemperatureSensor()); assertFalse(device.isHumiditySensor()); - assertFalse(device.isPowermeter()); + assertFalse(device.isPowerMeter()); assertFalse(device.isDectRepeater()); assertFalse(device.isHeatingThermostat()); assertFalse(device.hasMicrophone()); @@ -857,7 +857,7 @@ public void validateHANFUNDimmableLightModel() { assertNull(device.getTemperature()); - assertNull(device.getPowermeter()); + assertNull(device.getPowerMeter()); assertNull(device.getHkr()); @@ -887,7 +887,7 @@ public void validateHANFUNOnOffModel() { assertFalse(device.isHANFUNAlarmSensor()); assertFalse(device.isButton()); assertFalse(device.isHeatingThermostat()); - assertFalse(device.isPowermeter()); + assertFalse(device.isPowerMeter()); assertFalse(device.isTemperatureSensor()); assertFalse(device.isSwitchableOutlet()); assertFalse(device.isDectRepeater()); @@ -909,7 +909,7 @@ public void validateHANFUNOnOffModel() { assertNotNull(model); assertEquals(false, model.state); - assertNull(device.getPowermeter()); + assertNull(device.getPowerMeter()); assertNull(device.getHkr()); @@ -939,13 +939,13 @@ public void validateHeatingGroupModel() { assertFalse(group.isSwitchableOutlet()); assertFalse(group.isTemperatureSensor()); assertFalse(group.isHumiditySensor()); - assertFalse(group.isPowermeter()); + assertFalse(group.isPowerMeter()); assertTrue(group.isHeatingThermostat()); assertFalse(group.isHANFUNBlinds()); assertNull(group.getSwitch()); - assertNull(group.getPowermeter()); + assertNull(group.getPowerMeter()); validateHeatingModel(group.getHkr()); @@ -977,7 +977,7 @@ public void validateSwitchGroupModel() { assertTrue(group.isSwitchableOutlet()); assertFalse(group.isTemperatureSensor()); assertFalse(group.isHumiditySensor()); - assertTrue(group.isPowermeter()); + assertTrue(group.isPowerMeter()); assertFalse(group.isHeatingThermostat()); assertFalse(group.isHANFUNBlinds()); @@ -987,7 +987,7 @@ public void validateSwitchGroupModel() { assertEquals(BigDecimal.ZERO, group.getSwitch().getLock()); assertEquals(BigDecimal.ZERO, group.getSwitch().getDevicelock()); - validatePowerMeter(group.getPowermeter()); + validatePowerMeter(group.getPowerMeter()); assertNull(group.getHkr()); @@ -1024,7 +1024,7 @@ private void validateHeatingModel(HeatingModel model) { assertEquals(new BigDecimal("100"), model.getBattery()); assertEquals(BatteryModel.BATTERY_OFF, model.getBatterylow()); assertEquals(MODE_AUTO, model.getMode()); - assertEquals(MODE_COMFORT, model.getRadiatorMode()); + assertEquals(HEATING_MODE_COMFORT, model.getRadiatorMode()); assertNotNull(model.getNextchange()); assertEquals(1484341200, model.getNextchange().getEndperiod()); diff --git a/bundles/org.openhab.binding.avmfritz/src/test/java/org/openhab/binding/avmfritz/internal/dto/HeatingModelTest.java b/bundles/org.openhab.binding.avmfritz/src/test/java/org/openhab/binding/avmfritz/internal/dto/HeatingModelTest.java index 6e7ce713b2ae1..4633382794b8c 100644 --- a/bundles/org.openhab.binding.avmfritz/src/test/java/org/openhab/binding/avmfritz/internal/dto/HeatingModelTest.java +++ b/bundles/org.openhab.binding.avmfritz/src/test/java/org/openhab/binding/avmfritz/internal/dto/HeatingModelTest.java @@ -65,20 +65,20 @@ public void validateTemperatureNormalization() { @Test public void validateGetRadiatorModeReturnsValidMode() { HeatingModel heatingModel = new HeatingModel(); - assertEquals(MODE_UNKNOWN, heatingModel.getRadiatorMode()); + assertEquals(HEATING_MODE_UNKNOWN, heatingModel.getRadiatorMode()); heatingModel.setTsoll(BigDecimal.ONE); - assertEquals(MODE_ON, heatingModel.getRadiatorMode()); + assertEquals(HEATING_MODE_ON, heatingModel.getRadiatorMode()); heatingModel.setWindowopenactiv(new BigDecimal(1.0)); - assertEquals(MODE_WINDOW_OPEN, heatingModel.getRadiatorMode()); + assertEquals(HEATING_MODE_WINDOW_OPEN, heatingModel.getRadiatorMode()); heatingModel.setWindowopenactiv(new BigDecimal(0.0)); heatingModel.setKomfort(BigDecimal.ONE); - assertEquals(MODE_COMFORT, heatingModel.getRadiatorMode()); + assertEquals(HEATING_MODE_COMFORT, heatingModel.getRadiatorMode()); heatingModel.setKomfort(null); heatingModel.setBoostactive(new BigDecimal(1.0)); - assertEquals(MODE_BOOST, heatingModel.getRadiatorMode()); + assertEquals(HEATING_MODE_BOOST, heatingModel.getRadiatorMode()); } } diff --git a/itests/org.openhab.binding.avmfritz.tests/src/main/java/org/openhab/binding/avmfritz/internal/discovery/AVMFritzDiscoveryServiceOSGiTest.java b/itests/org.openhab.binding.avmfritz.tests/src/main/java/org/openhab/binding/avmfritz/internal/discovery/AVMFritzDiscoveryServiceOSGiTest.java index 9c2dc5b666b4e..e08eff1672b5e 100644 --- a/itests/org.openhab.binding.avmfritz.tests/src/main/java/org/openhab/binding/avmfritz/internal/discovery/AVMFritzDiscoveryServiceOSGiTest.java +++ b/itests/org.openhab.binding.avmfritz.tests/src/main/java/org/openhab/binding/avmfritz/internal/discovery/AVMFritzDiscoveryServiceOSGiTest.java @@ -189,7 +189,7 @@ public void validDECTRepeater100Result() throws JAXBException, XMLStreamExceptio assertEquals(BRIGE_THING_ID, discoveryResult.getBridgeUID()); assertEquals("087610954669", discoveryResult.getProperties().get(CONFIG_AIN)); assertEquals("AVM", discoveryResult.getProperties().get(PROPERTY_VENDOR)); - assertEquals("FRITZ!DECT Repeater 100", discoveryResult.getProperties().get(PRODUCT_NAME)); + assertEquals("FRITZ!DECT Repeater 100", discoveryResult.getProperties().get(PROPERTY_PRODUCT_NAME)); assertEquals("087610954669", discoveryResult.getProperties().get(PROPERTY_SERIAL_NUMBER)); assertEquals("03.86", discoveryResult.getProperties().get(PROPERTY_FIRMWARE_VERSION)); assertEquals(CONFIG_AIN, discoveryResult.getRepresentationProperty()); @@ -249,7 +249,7 @@ public void validSmart250DiscoveryResult() throws JAXBException, XMLStreamExcept assertEquals(BRIGE_THING_ID, discoveryResult.getBridgeUID()); assertEquals("12345-6789012-0", discoveryResult.getProperties().get(CONFIG_AIN)); assertEquals("AVM", discoveryResult.getProperties().get(PROPERTY_VENDOR)); - assertEquals("FRITZ!Smart Energy 250", discoveryResult.getProperties().get(PRODUCT_NAME)); + assertEquals("FRITZ!Smart Energy 250", discoveryResult.getProperties().get(PROPERTY_PRODUCT_NAME)); assertEquals("12345-6789012-0", discoveryResult.getProperties().get(PROPERTY_SERIAL_NUMBER)); assertEquals("03.65", discoveryResult.getProperties().get(PROPERTY_FIRMWARE_VERSION)); assertEquals(CONFIG_AIN, discoveryResult.getRepresentationProperty()); @@ -314,7 +314,7 @@ public void validDECT200DiscoveryResult() throws JAXBException, XMLStreamExcepti assertEquals(BRIGE_THING_ID, discoveryResult.getBridgeUID()); assertEquals("087610000434", discoveryResult.getProperties().get(CONFIG_AIN)); assertEquals("AVM", discoveryResult.getProperties().get(PROPERTY_VENDOR)); - assertEquals("FRITZ!DECT 200", discoveryResult.getProperties().get(PRODUCT_NAME)); + assertEquals("FRITZ!DECT 200", discoveryResult.getProperties().get(PROPERTY_PRODUCT_NAME)); assertEquals("087610000434", discoveryResult.getProperties().get(PROPERTY_SERIAL_NUMBER)); assertEquals("03.83", discoveryResult.getProperties().get(PROPERTY_FIRMWARE_VERSION)); assertEquals(CONFIG_AIN, discoveryResult.getRepresentationProperty()); @@ -367,7 +367,7 @@ public void validDECT210DiscoveryResult() throws JAXBException, XMLStreamExcepti assertEquals(BRIGE_THING_ID, discoveryResult.getBridgeUID()); assertEquals("087610000434", discoveryResult.getProperties().get(CONFIG_AIN)); assertEquals("AVM", discoveryResult.getProperties().get(PROPERTY_VENDOR)); - assertEquals("FRITZ!DECT 210", discoveryResult.getProperties().get(PRODUCT_NAME)); + assertEquals("FRITZ!DECT 210", discoveryResult.getProperties().get(PROPERTY_PRODUCT_NAME)); assertEquals("087610000434", discoveryResult.getProperties().get(PROPERTY_SERIAL_NUMBER)); assertEquals("03.83", discoveryResult.getProperties().get(PROPERTY_FIRMWARE_VERSION)); assertEquals(CONFIG_AIN, discoveryResult.getRepresentationProperty()); @@ -423,7 +423,7 @@ public void validCometDECTDiscoveryResult() throws JAXBException, XMLStreamExcep assertEquals(BRIGE_THING_ID, discoveryResult.getBridgeUID()); assertEquals("087610000435", discoveryResult.getProperties().get(CONFIG_AIN)); assertEquals("AVM", discoveryResult.getProperties().get(PROPERTY_VENDOR)); - assertEquals("Comet DECT", discoveryResult.getProperties().get(PRODUCT_NAME)); + assertEquals("Comet DECT", discoveryResult.getProperties().get(PROPERTY_PRODUCT_NAME)); assertEquals("087610000435", discoveryResult.getProperties().get(PROPERTY_SERIAL_NUMBER)); assertEquals("03.50", discoveryResult.getProperties().get(PROPERTY_FIRMWARE_VERSION)); assertEquals(CONFIG_AIN, discoveryResult.getRepresentationProperty()); @@ -479,7 +479,7 @@ public void validDECT300DiscoveryResult() throws JAXBException, XMLStreamExcepti assertEquals(BRIGE_THING_ID, discoveryResult.getBridgeUID()); assertEquals("087610000435", discoveryResult.getProperties().get(CONFIG_AIN)); assertEquals("AVM", discoveryResult.getProperties().get(PROPERTY_VENDOR)); - assertEquals("FRITZ!DECT 300", discoveryResult.getProperties().get(PRODUCT_NAME)); + assertEquals("FRITZ!DECT 300", discoveryResult.getProperties().get(PROPERTY_PRODUCT_NAME)); assertEquals("087610000435", discoveryResult.getProperties().get(PROPERTY_SERIAL_NUMBER)); assertEquals("03.50", discoveryResult.getProperties().get(PROPERTY_FIRMWARE_VERSION)); assertEquals(CONFIG_AIN, discoveryResult.getRepresentationProperty()); @@ -535,7 +535,7 @@ public void validDECT301DiscoveryResult() throws JAXBException, XMLStreamExcepti assertEquals(BRIGE_THING_ID, discoveryResult.getBridgeUID()); assertEquals("087610000435", discoveryResult.getProperties().get(CONFIG_AIN)); assertEquals("AVM", discoveryResult.getProperties().get(PROPERTY_VENDOR)); - assertEquals("FRITZ!DECT 301", discoveryResult.getProperties().get(PRODUCT_NAME)); + assertEquals("FRITZ!DECT 301", discoveryResult.getProperties().get(PROPERTY_PRODUCT_NAME)); assertEquals("087610000435", discoveryResult.getProperties().get(PROPERTY_SERIAL_NUMBER)); assertEquals("03.50", discoveryResult.getProperties().get(PROPERTY_FIRMWARE_VERSION)); assertEquals(CONFIG_AIN, discoveryResult.getRepresentationProperty()); @@ -584,7 +584,7 @@ public void validPowerline546EDiscoveryResult() throws JAXBException, XMLStreamE assertEquals(BRIGE_THING_ID, discoveryResult.getBridgeUID()); assertEquals("5C:49:79:F0:A3:84", discoveryResult.getProperties().get(CONFIG_AIN)); assertEquals("AVM", discoveryResult.getProperties().get(PROPERTY_VENDOR)); - assertEquals("FRITZ!Powerline 546E", discoveryResult.getProperties().get(PRODUCT_NAME)); + assertEquals("FRITZ!Powerline 546E", discoveryResult.getProperties().get(PROPERTY_PRODUCT_NAME)); assertEquals("5C:49:79:F0:A3:84", discoveryResult.getProperties().get(PROPERTY_SERIAL_NUMBER)); assertEquals("06.92", discoveryResult.getProperties().get(PROPERTY_FIRMWARE_VERSION)); assertEquals(CONFIG_AIN, discoveryResult.getRepresentationProperty()); @@ -657,7 +657,7 @@ public void validHANFUNMagneticContactDiscoveryResult() throws JAXBException, XM assertEquals(BRIGE_THING_ID, discoveryResult.getBridgeUID()); assertEquals("119340059578-1", discoveryResult.getProperties().get(CONFIG_AIN)); assertEquals("0x0feb", discoveryResult.getProperties().get(PROPERTY_VENDOR)); - assertEquals("HAN-FUN", discoveryResult.getProperties().get(PRODUCT_NAME)); + assertEquals("HAN-FUN", discoveryResult.getProperties().get(PROPERTY_PRODUCT_NAME)); assertEquals("119340059578-1", discoveryResult.getProperties().get(PROPERTY_SERIAL_NUMBER)); assertEquals("0.0", discoveryResult.getProperties().get(PROPERTY_FIRMWARE_VERSION)); assertEquals(CONFIG_AIN, discoveryResult.getRepresentationProperty()); @@ -703,7 +703,7 @@ public void validHANFUNOpticalContactDiscoveryResult() throws JAXBException, XML assertEquals(BRIGE_THING_ID, discoveryResult.getBridgeUID()); assertEquals("119340059578-1", discoveryResult.getProperties().get(CONFIG_AIN)); assertEquals("0x0feb", discoveryResult.getProperties().get(PROPERTY_VENDOR)); - assertEquals("HAN-FUN", discoveryResult.getProperties().get(PRODUCT_NAME)); + assertEquals("HAN-FUN", discoveryResult.getProperties().get(PROPERTY_PRODUCT_NAME)); assertEquals("119340059578-1", discoveryResult.getProperties().get(PROPERTY_SERIAL_NUMBER)); assertEquals("0.0", discoveryResult.getProperties().get(PROPERTY_FIRMWARE_VERSION)); assertEquals(CONFIG_AIN, discoveryResult.getRepresentationProperty()); @@ -749,7 +749,7 @@ public void validHANFUNMotionSensorDiscoveryResult() throws JAXBException, XMLSt assertEquals(BRIGE_THING_ID, discoveryResult.getBridgeUID()); assertEquals("119340059578-1", discoveryResult.getProperties().get(CONFIG_AIN)); assertEquals("0x0feb", discoveryResult.getProperties().get(PROPERTY_VENDOR)); - assertEquals("HAN-FUN", discoveryResult.getProperties().get(PRODUCT_NAME)); + assertEquals("HAN-FUN", discoveryResult.getProperties().get(PROPERTY_PRODUCT_NAME)); assertEquals("119340059578-1", discoveryResult.getProperties().get(PROPERTY_SERIAL_NUMBER)); assertEquals("0.0", discoveryResult.getProperties().get(PROPERTY_FIRMWARE_VERSION)); assertEquals(CONFIG_AIN, discoveryResult.getRepresentationProperty()); @@ -795,7 +795,7 @@ public void validHANFUNMSmokeDetectorDiscoveryResult() throws JAXBException, XML assertEquals(BRIGE_THING_ID, discoveryResult.getBridgeUID()); assertEquals("113240059952-1", discoveryResult.getProperties().get(CONFIG_AIN)); assertEquals("0x2c3c", discoveryResult.getProperties().get(PROPERTY_VENDOR)); - assertEquals("HAN-FUN", discoveryResult.getProperties().get(PRODUCT_NAME)); + assertEquals("HAN-FUN", discoveryResult.getProperties().get(PROPERTY_PRODUCT_NAME)); assertEquals("113240059952-1", discoveryResult.getProperties().get(PROPERTY_SERIAL_NUMBER)); assertEquals("0.0", discoveryResult.getProperties().get(PROPERTY_FIRMWARE_VERSION)); assertEquals(CONFIG_AIN, discoveryResult.getRepresentationProperty()); @@ -841,7 +841,7 @@ public void validHANFUNSwitchtDiscoveryResult() throws JAXBException, XMLStreamE assertEquals(BRIGE_THING_ID, discoveryResult.getBridgeUID()); assertEquals("119340059578-1", discoveryResult.getProperties().get(CONFIG_AIN)); assertEquals("0x0feb", discoveryResult.getProperties().get(PROPERTY_VENDOR)); - assertEquals("HAN-FUN", discoveryResult.getProperties().get(PRODUCT_NAME)); + assertEquals("HAN-FUN", discoveryResult.getProperties().get(PROPERTY_PRODUCT_NAME)); assertEquals("119340059578-1", discoveryResult.getProperties().get(PROPERTY_SERIAL_NUMBER)); assertEquals("0.0", discoveryResult.getProperties().get(PROPERTY_FIRMWARE_VERSION)); assertEquals(CONFIG_AIN, discoveryResult.getRepresentationProperty()); @@ -897,7 +897,7 @@ public void validHANFUNBlindDiscoveryResult() throws JAXBException, XMLStreamExc 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("Rollotron 1213", discoveryResult.getProperties().get(PROPERTY_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()); @@ -957,7 +957,7 @@ public void validHeatingGroupDiscoveryResult() throws JAXBException, XMLStreamEx assertEquals(BRIGE_THING_ID, discoveryResult.getBridgeUID()); assertEquals("F0:A3:7F-900", discoveryResult.getProperties().get(CONFIG_AIN)); assertEquals("AVM", discoveryResult.getProperties().get(PROPERTY_VENDOR)); - assertEquals("", discoveryResult.getProperties().get(PRODUCT_NAME)); + assertEquals("", discoveryResult.getProperties().get(PROPERTY_PRODUCT_NAME)); assertEquals("F0:A3:7F-900", discoveryResult.getProperties().get(PROPERTY_SERIAL_NUMBER)); assertEquals("1.0", discoveryResult.getProperties().get(PROPERTY_FIRMWARE_VERSION)); assertEquals("1000", discoveryResult.getProperties().get(PROPERTY_MASTER)); @@ -1012,7 +1012,7 @@ public void validSwitchGroupDiscoveryResult() throws JAXBException, XMLStreamExc assertEquals(BRIGE_THING_ID, discoveryResult.getBridgeUID()); assertEquals("F0:A3:7F-900", discoveryResult.getProperties().get(CONFIG_AIN)); assertEquals("AVM", discoveryResult.getProperties().get(PROPERTY_VENDOR)); - assertEquals("", discoveryResult.getProperties().get(PRODUCT_NAME)); + assertEquals("", discoveryResult.getProperties().get(PROPERTY_PRODUCT_NAME)); assertEquals("F0:A3:7F-900", discoveryResult.getProperties().get(PROPERTY_SERIAL_NUMBER)); assertEquals("1.0", discoveryResult.getProperties().get(PROPERTY_FIRMWARE_VERSION)); assertEquals("1000", discoveryResult.getProperties().get(PROPERTY_MASTER));