From d7e0ed749f9fe41d13d4394446ae60ff15a9fc02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Lange?= Date: Mon, 20 Feb 2023 06:59:40 +0100 Subject: [PATCH 01/13] Add POJOs for ecoFeedback from Miele REST API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Björn Lange --- .../webservice/api/json/EcoFeedback.java | 89 +++++++++++ .../api/json/EnergyConsumption.java | 71 +++++++++ .../internal/webservice/api/json/State.java | 16 +- .../webservice/api/json/WaterConsumption.java | 71 +++++++++ .../api/json/DeviceCollectionTest.java | 29 ++++ .../json/deviceCollectionWithEcoFeedback.json | 142 ++++++++++++++++++ 6 files changed, 413 insertions(+), 5 deletions(-) create mode 100644 bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/webservice/api/json/EcoFeedback.java create mode 100644 bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/webservice/api/json/EnergyConsumption.java create mode 100644 bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/webservice/api/json/WaterConsumption.java create mode 100644 bundles/org.openhab.binding.mielecloud/src/test/resources/org/openhab/binding/mielecloud/internal/webservice/api/json/deviceCollectionWithEcoFeedback.json diff --git a/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/webservice/api/json/EcoFeedback.java b/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/webservice/api/json/EcoFeedback.java new file mode 100644 index 0000000000000..f90cfd2071569 --- /dev/null +++ b/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/webservice/api/json/EcoFeedback.java @@ -0,0 +1,89 @@ +/** + * Copyright (c) 2010-2023 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.mielecloud.internal.webservice.api.json; + +import java.util.Objects; +import java.util.Optional; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; + +/** + * Immutable POJO representing the amount of water and energy used by the current running program up to the present + * moment. Queried from the Miele REST API. + * + * @author Björn Lange - Initial contribution + */ +@NonNullByDefault +public class EcoFeedback { + @Nullable + private WaterConsumption currentWaterConsumption; + @Nullable + private EnergyConsumption currentEnergyConsumption; + @Nullable + private Double waterForecast; + @Nullable + private Double energyForecast; + + public Optional getCurrentWaterConsumption() { + return Optional.ofNullable(currentWaterConsumption); + } + + public Optional getCurrentEnergyConsumption() { + return Optional.ofNullable(currentEnergyConsumption); + } + + /** + * Gets the relative water usage for the selected program from 0 to 1. + */ + public Optional getWaterForecast() { + return Optional.ofNullable(waterForecast); + } + + /** + * Gets the relative energy usage for the selected program from 0 to 1. + */ + public Optional getEnergyForecast() { + return Optional.ofNullable(energyForecast); + } + + @Override + public int hashCode() { + return Objects.hash(currentWaterConsumption, currentEnergyConsumption, waterForecast, energyForecast); + } + + @Override + public boolean equals(@Nullable Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + EcoFeedback other = (EcoFeedback) obj; + return Objects.equals(currentWaterConsumption, other.currentWaterConsumption) + && Objects.equals(currentEnergyConsumption, other.currentEnergyConsumption) + && Objects.equals(waterForecast, other.waterForecast) + && Objects.equals(energyForecast, other.energyForecast); + } + + @Override + public String toString() { + return "EcoFeedback [currentWaterConsumption=" + currentWaterConsumption + ", currentEnergyConsumption=" + + currentEnergyConsumption + ", waterForecast=" + waterForecast + ", energyForecast=" + energyForecast + + "]"; + } +} diff --git a/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/webservice/api/json/EnergyConsumption.java b/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/webservice/api/json/EnergyConsumption.java new file mode 100644 index 0000000000000..8bdf770de24cf --- /dev/null +++ b/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/webservice/api/json/EnergyConsumption.java @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2010-2023 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.mielecloud.internal.webservice.api.json; + +import java.util.Objects; +import java.util.Optional; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; + +/** + * Immutable POJO representing an amount of consumed energy. Queried from the Miele REST API. + * + * @author Björn Lange - Initial contribution + */ +@NonNullByDefault +public class EnergyConsumption { + @Nullable + private String unit; + @Nullable + private Double value; + + /** + * Gets the measurement unit which represents energy. + */ + public Optional getUnit() { + return Optional.ofNullable(unit); + } + + /** + * Gets the amount of energy. + */ + public Optional getValue() { + return Optional.ofNullable(value); + } + + @Override + public int hashCode() { + return Objects.hash(unit, value); + } + + @Override + public boolean equals(@Nullable Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + EnergyConsumption other = (EnergyConsumption) obj; + return Objects.equals(unit, other.unit) && Objects.equals(value, other.value); + } + + @Override + public String toString() { + return "EnergyConsumption [unit=" + unit + ", value=" + value + "]"; + } +} diff --git a/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/webservice/api/json/State.java b/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/webservice/api/json/State.java index 6b813e7a08934..e95bcca8fb624 100644 --- a/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/webservice/api/json/State.java +++ b/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/webservice/api/json/State.java @@ -25,7 +25,7 @@ * * @author Björn Lange - Initial contribution * @author Benjamin Bolte - Add plate step - * @author Björn Lange - Add elapsed time channel + * @author Björn Lange - Add elapsed time channel, add eco feedback */ @NonNullByDefault public class State { @@ -74,6 +74,8 @@ public class State { @Nullable private final List plateStep = null; @Nullable + private EcoFeedback ecoFeedback; + @Nullable private Integer batteryLevel; public Optional getStatus() { @@ -189,6 +191,10 @@ public List getPlateStep() { return Collections.unmodifiableList(plateStep); } + public Optional getEcoFeedback() { + return Optional.ofNullable(ecoFeedback); + } + public Optional getBatteryLevel() { return Optional.ofNullable(batteryLevel); } @@ -197,7 +203,7 @@ public Optional getBatteryLevel() { public int hashCode() { return Objects.hash(dryingStep, elapsedTime, light, programPhase, ProgramID, programId, programType, remainingTime, remoteEnable, signalDoor, signalFailure, signalInfo, startTime, status, - targetTemperature, temperature, ventilationStep, plateStep, batteryLevel); + targetTemperature, temperature, ventilationStep, plateStep, ecoFeedback, batteryLevel); } @Override @@ -222,7 +228,7 @@ public boolean equals(@Nullable Object obj) { && Objects.equals(targetTemperature, other.targetTemperature) && Objects.equals(temperature, other.temperature) && Objects.equals(ventilationStep, other.ventilationStep) && Objects.equals(plateStep, other.plateStep) - && Objects.equals(batteryLevel, other.batteryLevel); + && Objects.equals(ecoFeedback, other.ecoFeedback) && Objects.equals(batteryLevel, other.batteryLevel); } @Override @@ -232,7 +238,7 @@ public String toString() { + ", targetTemperature=" + targetTemperature + ", temperature=" + temperature + ", signalInfo=" + signalInfo + ", signalFailure=" + signalFailure + ", signalDoor=" + signalDoor + ", remoteEnable=" + remoteEnable + ", light=" + light + ", elapsedTime=" + elapsedTime + ", dryingStep=" + dryingStep - + ", ventilationStep=" + ventilationStep + ", plateStep=" + plateStep + ", batteryLevel=" + batteryLevel - + "]"; + + ", ventilationStep=" + ventilationStep + ", plateStep=" + plateStep + ", ecoFeedback=" + ecoFeedback + + ", batteryLevel=" + batteryLevel + "]"; } } diff --git a/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/webservice/api/json/WaterConsumption.java b/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/webservice/api/json/WaterConsumption.java new file mode 100644 index 0000000000000..aa95995e64ca1 --- /dev/null +++ b/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/webservice/api/json/WaterConsumption.java @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2010-2023 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.mielecloud.internal.webservice.api.json; + +import java.util.Objects; +import java.util.Optional; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; + +/** + * Immutable POJO representing an amount of consumed water. Queried from the Miele REST API. + * + * @author Björn Lange - Initial contribution + */ +@NonNullByDefault +public class WaterConsumption { + @Nullable + private String unit; + @Nullable + private Double value; + + /** + * Gets the measurement unit which represents a volume. + */ + public Optional getUnit() { + return Optional.ofNullable(unit); + } + + /** + * Gets the amount of water. + */ + public Optional getValue() { + return Optional.ofNullable(value); + } + + @Override + public int hashCode() { + return Objects.hash(unit, value); + } + + @Override + public boolean equals(@Nullable Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + WaterConsumption other = (WaterConsumption) obj; + return Objects.equals(unit, other.unit) && Objects.equals(value, other.value); + } + + @Override + public String toString() { + return "WaterConsumption [unit=" + unit + ", value=" + value + "]"; + } +} diff --git a/bundles/org.openhab.binding.mielecloud/src/test/java/org/openhab/binding/mielecloud/internal/webservice/api/json/DeviceCollectionTest.java b/bundles/org.openhab.binding.mielecloud/src/test/java/org/openhab/binding/mielecloud/internal/webservice/api/json/DeviceCollectionTest.java index b73051127c032..26c9325e11993 100644 --- a/bundles/org.openhab.binding.mielecloud/src/test/java/org/openhab/binding/mielecloud/internal/webservice/api/json/DeviceCollectionTest.java +++ b/bundles/org.openhab.binding.mielecloud/src/test/java/org/openhab/binding/mielecloud/internal/webservice/api/json/DeviceCollectionTest.java @@ -26,6 +26,7 @@ /** * @author Björn Lange - Initial contribution * @author Benjamin Bolte - Add plate step + * @author Björn Lange - Add eco feedback */ @NonNullByDefault public class DeviceCollectionTest { @@ -287,4 +288,32 @@ public void testCreateDeviceCollectionWithFloatingPointTemperature() throws IOEx assertEquals(Integer.valueOf(0), targetTemperature.getValueLocalized().get()); assertEquals("Celsius", targetTemperature.getUnit().get()); } + + @Test + public void testCreateDeviceCollectionWithEcoFeedback() throws IOException { + // given: + String json = getResourceAsString( + "/org/openhab/binding/mielecloud/internal/webservice/api/json/deviceCollectionWithEcoFeedback.json"); + + // when: + DeviceCollection collection = DeviceCollection.fromJson(json); + + // then: + assertEquals(1, collection.getDeviceIdentifiers().size()); + Device device = collection.getDevice(collection.getDeviceIdentifiers().iterator().next()); + + State state = device.getState().get(); + EcoFeedback ecoFeedback = state.getEcoFeedback().get(); + + WaterConsumption currentWaterConsumption = ecoFeedback.getCurrentWaterConsumption().get(); + assertEquals("l", currentWaterConsumption.getUnit().get()); + assertEquals(0.0, currentWaterConsumption.getValue().get()); + + EnergyConsumption currentEnergyConsumption = ecoFeedback.getCurrentEnergyConsumption().get(); + assertEquals("kWh", currentEnergyConsumption.getUnit().get()); + assertEquals(0.5, currentEnergyConsumption.getValue().get()); + + assertEquals(0.0, ecoFeedback.getWaterForecast().get()); + assertEquals(0.6, ecoFeedback.getEnergyForecast().get()); + } } diff --git a/bundles/org.openhab.binding.mielecloud/src/test/resources/org/openhab/binding/mielecloud/internal/webservice/api/json/deviceCollectionWithEcoFeedback.json b/bundles/org.openhab.binding.mielecloud/src/test/resources/org/openhab/binding/mielecloud/internal/webservice/api/json/deviceCollectionWithEcoFeedback.json new file mode 100644 index 0000000000000..6ca3226062936 --- /dev/null +++ b/bundles/org.openhab.binding.mielecloud/src/test/resources/org/openhab/binding/mielecloud/internal/webservice/api/json/deviceCollectionWithEcoFeedback.json @@ -0,0 +1,142 @@ +{ + "000124430017": { + "ident": { + "type": { + "key_localized": "Device type", + "value_raw": 2, + "value_localized": "Tumble dryer" + }, + "deviceName": "TWH780WP", + "protocolVersion": 4, + "deviceIdentLabel": { + "fabNumber": "000124430017", + "fabIndex": "44", + "techType": "TWH780WP", + "matNumber": "11219891", + "swids": [ + "5678", + "25359", + "25360", + "20559", + "25277", + "5136", + "20445", + "25234", + "4657" + ] + }, + "xkmIdentLabel": { + "techType": "EK057", + "releaseVersion": "08.10" + } + }, + "state": { + "ProgramID": { + "value_raw": 2, + "value_localized": "Cottons", + "key_localized": "Program name" + }, + "status": { + "value_raw": 5, + "value_localized": "In use", + "key_localized": "status" + }, + "programType": { + "value_raw": 3, + "value_localized": "Cleaning/Care programme", + "key_localized": "Program type" + }, + "programPhase": { + "value_raw": 514, + "value_localized": "Drying", + "key_localized": "Program phase" + }, + "remainingTime": [ + 2, + 7 + ], + "startTime": [ + 0, + 0 + ], + "targetTemperature": [ + { + "value_raw": -32768, + "value_localized": null, + "unit": "Celsius" + }, + { + "value_raw": -32768, + "value_localized": null, + "unit": "Celsius" + }, + { + "value_raw": -32768, + "value_localized": null, + "unit": "Celsius" + } + ], + "temperature": [ + { + "value_raw": -32768, + "value_localized": null, + "unit": "Celsius" + }, + { + "value_raw": -32768, + "value_localized": null, + "unit": "Celsius" + }, + { + "value_raw": -32768, + "value_localized": null, + "unit": "Celsius" + } + ], + "signalInfo": false, + "signalFailure": false, + "signalDoor": false, + "remoteEnable": { + "fullRemoteControl": true, + "smartGrid": false, + "mobileStart": false + }, + "ambientLight": null, + "light": null, + "elapsedTime": [ + 1, + 9 + ], + "spinningSpeed": { + "unit": "rpm", + "value_raw": null, + "value_localized": null, + "key_localized": "Spin speed" + }, + "dryingStep": { + "value_raw": 0, + "value_localized": "Extra dry", + "key_localized": "Drying level" + }, + "ventilationStep": { + "value_raw": null, + "value_localized": "", + "key_localized": "Fan level" + }, + "plateStep": [], + "ecoFeedback": { + "currentWaterConsumption": { + "unit": "l", + "value": 0 + }, + "currentEnergyConsumption": { + "unit": "kWh", + "value": 0.5 + }, + "waterForecast": 0, + "energyForecast": 0.6 + }, + "batteryLevel": null + } + } +} \ No newline at end of file From 256d61bec5bc5681584e5593a1848f895fca26b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Lange?= Date: Mon, 20 Feb 2023 06:59:48 +0100 Subject: [PATCH 02/13] DeviceState offers water and energy consumption MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Björn Lange --- .../internal/webservice/api/DeviceState.java | 33 +- .../internal/webservice/api/Quantity.java | 70 ++++ .../webservice/api/DeviceStateTest.java | 335 +++++++++++++++++- 3 files changed, 436 insertions(+), 2 deletions(-) create mode 100644 bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/webservice/api/Quantity.java diff --git a/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/webservice/api/DeviceState.java b/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/webservice/api/DeviceState.java index 7c99e1b54f3f8..64477b6f911d3 100644 --- a/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/webservice/api/DeviceState.java +++ b/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/webservice/api/DeviceState.java @@ -22,6 +22,7 @@ import org.openhab.binding.mielecloud.internal.webservice.api.json.DeviceIdentLabel; import org.openhab.binding.mielecloud.internal.webservice.api.json.DeviceType; import org.openhab.binding.mielecloud.internal.webservice.api.json.DryingStep; +import org.openhab.binding.mielecloud.internal.webservice.api.json.EcoFeedback; import org.openhab.binding.mielecloud.internal.webservice.api.json.Ident; import org.openhab.binding.mielecloud.internal.webservice.api.json.Light; import org.openhab.binding.mielecloud.internal.webservice.api.json.PlateStep; @@ -43,7 +44,7 @@ * @author Björn Lange - Introduced null handling * @author Benjamin Bolte - Add pre-heat finished, plate step, door state, door alarm, info state channel and map signal * flags from API - * @author Björn Lange - Add elapsed time channel, dish warmer and robotic vacuum cleaner things + * @author Björn Lange - Add elapsed time channel, dish warmer and robotic vacuum cleaner things, eco feedback */ @NonNullByDefault public class DeviceState { @@ -458,6 +459,36 @@ public Optional getDoorAlarm() { return Optional.of(doorState.get() && failure.get()); } + /** + * Gets the amount of water consumed since the currently running program started. + * + * @return The amount of water consumed since the currently running program started. + */ + public Optional getCurrentWaterConsumption() { + if (deviceIsInOffState()) { + return Optional.empty(); + } + + return device.flatMap(Device::getState).flatMap(State::getEcoFeedback) + .flatMap(EcoFeedback::getCurrentWaterConsumption).flatMap(consumption -> consumption.getValue() + .map(value -> new Quantity(value, consumption.getUnit().orElse(null)))); + } + + /** + * Gets the amount of energy consumed since the currently running program started. + * + * @return The amount of energy consumed since the currently running program started. + */ + public Optional getCurrentEnergyConsumption() { + if (deviceIsInOffState()) { + return Optional.empty(); + } + + return device.flatMap(Device::getState).flatMap(State::getEcoFeedback) + .flatMap(EcoFeedback::getCurrentEnergyConsumption).flatMap(consumption -> consumption.getValue() + .map(value -> new Quantity(value, consumption.getUnit().orElse(null)))); + } + /** * Gets the battery level. * diff --git a/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/webservice/api/Quantity.java b/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/webservice/api/Quantity.java new file mode 100644 index 0000000000000..f5291900cb741 --- /dev/null +++ b/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/webservice/api/Quantity.java @@ -0,0 +1,70 @@ +/** + * Copyright (c) 2010-2023 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.mielecloud.internal.webservice.api; + +import java.util.Objects; +import java.util.Optional; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; + +/** + * A physical quantity as obtained from the Miele REST API. + * + * @author Björn Lange - Initial contribution + */ +@NonNullByDefault +public class Quantity { + double value; + Optional unit; + + public Quantity(double value, @Nullable String unit) { + this.value = value; + this.unit = Optional.ofNullable(unit); + } + + public double getValue() { + return value; + } + + public Optional getUnit() { + return unit; + } + + @Override + public int hashCode() { + return Objects.hash(value, unit); + } + + @Override + public boolean equals(@Nullable Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + Quantity other = (Quantity) obj; + return Double.doubleToLongBits(value) == Double.doubleToLongBits(other.value) + && Objects.equals(unit, other.unit); + } + + @Override + public String toString() { + return "Quantity [value=" + value + ", unit=" + unit + "]"; + } +} diff --git a/bundles/org.openhab.binding.mielecloud/src/test/java/org/openhab/binding/mielecloud/internal/webservice/api/DeviceStateTest.java b/bundles/org.openhab.binding.mielecloud/src/test/java/org/openhab/binding/mielecloud/internal/webservice/api/DeviceStateTest.java index d2387d0d0f785..616c9fbdd0c89 100644 --- a/bundles/org.openhab.binding.mielecloud/src/test/java/org/openhab/binding/mielecloud/internal/webservice/api/DeviceStateTest.java +++ b/bundles/org.openhab.binding.mielecloud/src/test/java/org/openhab/binding/mielecloud/internal/webservice/api/DeviceStateTest.java @@ -26,6 +26,8 @@ import org.openhab.binding.mielecloud.internal.webservice.api.json.DeviceIdentLabel; import org.openhab.binding.mielecloud.internal.webservice.api.json.DeviceType; import org.openhab.binding.mielecloud.internal.webservice.api.json.DryingStep; +import org.openhab.binding.mielecloud.internal.webservice.api.json.EcoFeedback; +import org.openhab.binding.mielecloud.internal.webservice.api.json.EnergyConsumption; import org.openhab.binding.mielecloud.internal.webservice.api.json.Ident; import org.openhab.binding.mielecloud.internal.webservice.api.json.Light; import org.openhab.binding.mielecloud.internal.webservice.api.json.PlateStep; @@ -40,12 +42,13 @@ import org.openhab.binding.mielecloud.internal.webservice.api.json.Temperature; import org.openhab.binding.mielecloud.internal.webservice.api.json.Type; import org.openhab.binding.mielecloud.internal.webservice.api.json.VentilationStep; +import org.openhab.binding.mielecloud.internal.webservice.api.json.WaterConsumption; /** * @author Björn Lange - Initial contribution * @author Benjamin Bolte - Add pre-heat finished, plate step, door state, door alarm and info state channels and map * signal flags from API - * @author Björn Lange - Add elapsed time channel, robotic vacuum cleaner + * @author Björn Lange - Add elapsed time channel, robotic vacuum cleaner, eco feedback */ @NonNullByDefault public class DeviceStateTest { @@ -2106,6 +2109,336 @@ public void testGetLightStateWhenLightIsNotSupported() { assertFalse(lightState.isPresent()); } + @Test + public void testGetCurrentWaterConsumptionWhenEcoFeedbackIsNotPresent() { + // given: + Status status = mock(Status.class); + when(status.getValueRaw()).thenReturn(Optional.of(StateType.ON.getCode())); + + State state = mock(State.class); + when(state.getStatus()).thenReturn(Optional.of(status)); + when(state.getEcoFeedback()).thenReturn(Optional.empty()); + + Device device = mock(Device.class); + when(device.getState()).thenReturn(Optional.of(state)); + + DeviceState deviceState = new DeviceState(DEVICE_IDENTIFIER, device); + + // when: + Optional waterConsumption = deviceState.getCurrentWaterConsumption(); + + // then: + assertFalse(waterConsumption.isPresent()); + } + + @Test + public void testGetCurrentWaterConsumptionWhenCurrentWaterConsumptionIsNotPresent() { + // given: + Status status = mock(Status.class); + when(status.getValueRaw()).thenReturn(Optional.of(StateType.ON.getCode())); + + EcoFeedback ecoFeedback = mock(EcoFeedback.class); + when(ecoFeedback.getCurrentWaterConsumption()).thenReturn(Optional.empty()); + + State state = mock(State.class); + when(state.getStatus()).thenReturn(Optional.of(status)); + when(state.getEcoFeedback()).thenReturn(Optional.of(ecoFeedback)); + + Device device = mock(Device.class); + when(device.getState()).thenReturn(Optional.of(state)); + + DeviceState deviceState = new DeviceState(DEVICE_IDENTIFIER, device); + + // when: + Optional waterConsumption = deviceState.getCurrentWaterConsumption(); + + // then: + assertFalse(waterConsumption.isPresent()); + } + + @Test + public void testGetCurrentWaterConsumptionWhenCurrentWaterConsumptionIsEmpty() { + // given: + Status status = mock(Status.class); + when(status.getValueRaw()).thenReturn(Optional.of(StateType.ON.getCode())); + + WaterConsumption currentWaterConsumption = mock(WaterConsumption.class); + when(currentWaterConsumption.getUnit()).thenReturn(Optional.empty()); + when(currentWaterConsumption.getValue()).thenReturn(Optional.empty()); + + EcoFeedback ecoFeedback = mock(EcoFeedback.class); + when(ecoFeedback.getCurrentWaterConsumption()).thenReturn(Optional.of(currentWaterConsumption)); + + State state = mock(State.class); + when(state.getStatus()).thenReturn(Optional.of(status)); + when(state.getEcoFeedback()).thenReturn(Optional.of(ecoFeedback)); + + Device device = mock(Device.class); + when(device.getState()).thenReturn(Optional.of(state)); + + DeviceState deviceState = new DeviceState(DEVICE_IDENTIFIER, device); + + // when: + Optional waterConsumption = deviceState.getCurrentWaterConsumption(); + + // then: + assertFalse(waterConsumption.isPresent()); + } + + @Test + public void testGetCurrentWaterConsumptionWhenValueIsNotPresent() { + // given: + Status status = mock(Status.class); + when(status.getValueRaw()).thenReturn(Optional.of(StateType.ON.getCode())); + + WaterConsumption currentWaterConsumption = mock(WaterConsumption.class); + when(currentWaterConsumption.getUnit()).thenReturn(Optional.of("l")); + when(currentWaterConsumption.getValue()).thenReturn(Optional.empty()); + + EcoFeedback ecoFeedback = mock(EcoFeedback.class); + when(ecoFeedback.getCurrentWaterConsumption()).thenReturn(Optional.of(currentWaterConsumption)); + + State state = mock(State.class); + when(state.getStatus()).thenReturn(Optional.of(status)); + when(state.getEcoFeedback()).thenReturn(Optional.of(ecoFeedback)); + + Device device = mock(Device.class); + when(device.getState()).thenReturn(Optional.of(state)); + + DeviceState deviceState = new DeviceState(DEVICE_IDENTIFIER, device); + + // when: + Optional waterConsumption = deviceState.getCurrentWaterConsumption(); + + // then: + assertFalse(waterConsumption.isPresent()); + } + + @Test + public void testGetCurrentWaterConsumptionWhenUnitIsNotPresent() { + // given: + Status status = mock(Status.class); + when(status.getValueRaw()).thenReturn(Optional.of(StateType.ON.getCode())); + + WaterConsumption currentWaterConsumption = mock(WaterConsumption.class); + when(currentWaterConsumption.getUnit()).thenReturn(Optional.empty()); + when(currentWaterConsumption.getValue()).thenReturn(Optional.of(0.5)); + + EcoFeedback ecoFeedback = mock(EcoFeedback.class); + when(ecoFeedback.getCurrentWaterConsumption()).thenReturn(Optional.of(currentWaterConsumption)); + + State state = mock(State.class); + when(state.getStatus()).thenReturn(Optional.of(status)); + when(state.getEcoFeedback()).thenReturn(Optional.of(ecoFeedback)); + + Device device = mock(Device.class); + when(device.getState()).thenReturn(Optional.of(state)); + + DeviceState deviceState = new DeviceState(DEVICE_IDENTIFIER, device); + + // when: + Quantity waterConsumption = deviceState.getCurrentWaterConsumption().get(); + + // then: + assertEquals(0.5, waterConsumption.getValue()); + assertFalse(waterConsumption.getUnit().isPresent()); + } + + @Test + public void testGetCurrentWaterConsumption() { + // given: + Status status = mock(Status.class); + when(status.getValueRaw()).thenReturn(Optional.of(StateType.ON.getCode())); + + WaterConsumption currentWaterConsumption = mock(WaterConsumption.class); + when(currentWaterConsumption.getUnit()).thenReturn(Optional.of("l")); + when(currentWaterConsumption.getValue()).thenReturn(Optional.of(0.5)); + + EcoFeedback ecoFeedback = mock(EcoFeedback.class); + when(ecoFeedback.getCurrentWaterConsumption()).thenReturn(Optional.of(currentWaterConsumption)); + + State state = mock(State.class); + when(state.getStatus()).thenReturn(Optional.of(status)); + when(state.getEcoFeedback()).thenReturn(Optional.of(ecoFeedback)); + + Device device = mock(Device.class); + when(device.getState()).thenReturn(Optional.of(state)); + + DeviceState deviceState = new DeviceState(DEVICE_IDENTIFIER, device); + + // when: + Quantity waterConsumption = deviceState.getCurrentWaterConsumption().get(); + + // then: + assertEquals(0.5, waterConsumption.getValue()); + assertEquals(Optional.of("l"), waterConsumption.getUnit()); + } + + @Test + public void testGetCurrentEnergyConsumptionWhenEcoFeedbackIsNotPresent() { + // given: + Status status = mock(Status.class); + when(status.getValueRaw()).thenReturn(Optional.of(StateType.ON.getCode())); + + State state = mock(State.class); + when(state.getStatus()).thenReturn(Optional.of(status)); + when(state.getEcoFeedback()).thenReturn(Optional.empty()); + + Device device = mock(Device.class); + when(device.getState()).thenReturn(Optional.of(state)); + + DeviceState deviceState = new DeviceState(DEVICE_IDENTIFIER, device); + + // when: + Optional energyConsumption = deviceState.getCurrentEnergyConsumption(); + + // then: + assertFalse(energyConsumption.isPresent()); + } + + @Test + public void testGetCurrentEnergyConsumptionWhenCurrentEnergyConsumptionIsNotPresent() { + // given: + Status status = mock(Status.class); + when(status.getValueRaw()).thenReturn(Optional.of(StateType.ON.getCode())); + + EcoFeedback ecoFeedback = mock(EcoFeedback.class); + when(ecoFeedback.getCurrentEnergyConsumption()).thenReturn(Optional.empty()); + + State state = mock(State.class); + when(state.getStatus()).thenReturn(Optional.of(status)); + when(state.getEcoFeedback()).thenReturn(Optional.of(ecoFeedback)); + + Device device = mock(Device.class); + when(device.getState()).thenReturn(Optional.of(state)); + + DeviceState deviceState = new DeviceState(DEVICE_IDENTIFIER, device); + + // when: + Optional energyConsumption = deviceState.getCurrentEnergyConsumption(); + + // then: + assertFalse(energyConsumption.isPresent()); + } + + @Test + public void testGetCurrentEnergyConsumptionWhenCurrentEnergyConsumptionIsEmpty() { + // given: + Status status = mock(Status.class); + when(status.getValueRaw()).thenReturn(Optional.of(StateType.ON.getCode())); + + EnergyConsumption currentEnergyConsumption = mock(EnergyConsumption.class); + when(currentEnergyConsumption.getUnit()).thenReturn(Optional.empty()); + when(currentEnergyConsumption.getValue()).thenReturn(Optional.empty()); + + EcoFeedback ecoFeedback = mock(EcoFeedback.class); + when(ecoFeedback.getCurrentEnergyConsumption()).thenReturn(Optional.of(currentEnergyConsumption)); + + State state = mock(State.class); + when(state.getStatus()).thenReturn(Optional.of(status)); + when(state.getEcoFeedback()).thenReturn(Optional.of(ecoFeedback)); + + Device device = mock(Device.class); + when(device.getState()).thenReturn(Optional.of(state)); + + DeviceState deviceState = new DeviceState(DEVICE_IDENTIFIER, device); + + // when: + Optional energyConsumption = deviceState.getCurrentEnergyConsumption(); + + // then: + assertFalse(energyConsumption.isPresent()); + } + + @Test + public void testGetCurrentEnergyConsumptionWhenValueIsNotPresent() { + // given: + Status status = mock(Status.class); + when(status.getValueRaw()).thenReturn(Optional.of(StateType.ON.getCode())); + + EnergyConsumption currentEnergyConsumption = mock(EnergyConsumption.class); + when(currentEnergyConsumption.getUnit()).thenReturn(Optional.of("kWh")); + when(currentEnergyConsumption.getValue()).thenReturn(Optional.empty()); + + EcoFeedback ecoFeedback = mock(EcoFeedback.class); + when(ecoFeedback.getCurrentEnergyConsumption()).thenReturn(Optional.of(currentEnergyConsumption)); + + State state = mock(State.class); + when(state.getStatus()).thenReturn(Optional.of(status)); + when(state.getEcoFeedback()).thenReturn(Optional.of(ecoFeedback)); + + Device device = mock(Device.class); + when(device.getState()).thenReturn(Optional.of(state)); + + DeviceState deviceState = new DeviceState(DEVICE_IDENTIFIER, device); + + // when: + Optional energyConsumption = deviceState.getCurrentEnergyConsumption(); + + // then: + assertFalse(energyConsumption.isPresent()); + } + + @Test + public void testGetCurrentEnergyConsumptionWhenUnitIsNotPresent() { + // given: + Status status = mock(Status.class); + when(status.getValueRaw()).thenReturn(Optional.of(StateType.ON.getCode())); + + EnergyConsumption currentEnergyConsumption = mock(EnergyConsumption.class); + when(currentEnergyConsumption.getUnit()).thenReturn(Optional.empty()); + when(currentEnergyConsumption.getValue()).thenReturn(Optional.of(0.5)); + + EcoFeedback ecoFeedback = mock(EcoFeedback.class); + when(ecoFeedback.getCurrentEnergyConsumption()).thenReturn(Optional.of(currentEnergyConsumption)); + + State state = mock(State.class); + when(state.getStatus()).thenReturn(Optional.of(status)); + when(state.getEcoFeedback()).thenReturn(Optional.of(ecoFeedback)); + + Device device = mock(Device.class); + when(device.getState()).thenReturn(Optional.of(state)); + + DeviceState deviceState = new DeviceState(DEVICE_IDENTIFIER, device); + + // when: + Quantity energyConsumption = deviceState.getCurrentEnergyConsumption().get(); + + // then: + assertEquals(0.5, energyConsumption.getValue()); + assertFalse(energyConsumption.getUnit().isPresent()); + } + + @Test + public void testGetCurrentEnergyConsumption() { + // given: + Status status = mock(Status.class); + when(status.getValueRaw()).thenReturn(Optional.of(StateType.ON.getCode())); + + EnergyConsumption currentEnergyConsumption = mock(EnergyConsumption.class); + when(currentEnergyConsumption.getUnit()).thenReturn(Optional.of("kWh")); + when(currentEnergyConsumption.getValue()).thenReturn(Optional.of(0.5)); + + EcoFeedback ecoFeedback = mock(EcoFeedback.class); + when(ecoFeedback.getCurrentEnergyConsumption()).thenReturn(Optional.of(currentEnergyConsumption)); + + State state = mock(State.class); + when(state.getStatus()).thenReturn(Optional.of(status)); + when(state.getEcoFeedback()).thenReturn(Optional.of(ecoFeedback)); + + Device device = mock(Device.class); + when(device.getState()).thenReturn(Optional.of(state)); + + DeviceState deviceState = new DeviceState(DEVICE_IDENTIFIER, device); + + // when: + Quantity energyConsumption = deviceState.getCurrentEnergyConsumption().get(); + + // then: + assertEquals(0.5, energyConsumption.getValue()); + assertEquals(Optional.of("kWh"), energyConsumption.getUnit()); + } + @Test public void testGetBatteryLevel() { // given: From 774ebef9e4bed5f6f00d862075ee696d1ad39e4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Lange?= Date: Mon, 20 Feb 2023 06:59:50 +0100 Subject: [PATCH 03/13] Convert Quantity to State for channel population MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Björn Lange --- .../handler/channel/ChannelTypeUtil.java | 55 +++++++++++++++++++ .../handler/channel/DeviceChannelState.java | 10 +++- .../handler/channel/ChannelTypeUtilTest.java | 53 ++++++++++++++++++ 3 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 bundles/org.openhab.binding.mielecloud/src/test/java/org/openhab/binding/mielecloud/internal/handler/channel/ChannelTypeUtilTest.java diff --git a/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/handler/channel/ChannelTypeUtil.java b/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/handler/channel/ChannelTypeUtil.java index 864de6975733b..7d323dd056bd6 100644 --- a/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/handler/channel/ChannelTypeUtil.java +++ b/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/handler/channel/ChannelTypeUtil.java @@ -13,9 +13,12 @@ package org.openhab.binding.mielecloud.internal.handler.channel; import java.math.BigDecimal; +import java.text.NumberFormat; +import java.util.Locale; import java.util.Optional; import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.binding.mielecloud.internal.webservice.api.Quantity; import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.QuantityType; @@ -23,6 +26,8 @@ import org.openhab.core.library.unit.SIUnits; import org.openhab.core.types.State; import org.openhab.core.types.UnDefType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Utility class handling type conversions from Java types to channel types. @@ -31,6 +36,8 @@ */ @NonNullByDefault public final class ChannelTypeUtil { + private static final Logger logger = LoggerFactory.getLogger(ChannelTypeUtil.class); + private ChannelTypeUtil() { throw new IllegalStateException("ChannelTypeUtil cannot be instantiated."); } @@ -71,4 +78,52 @@ public static State intToTemperatureState(Optional value) { // The Miele 3rd Party API always provides temperatures in °C (even if the device uses another unit). return value.map(v -> (State) new QuantityType<>(v, SIUnits.CELSIUS)).orElse(UnDefType.UNDEF); } + + /** + * Converts an {@link Optional} of {@link Quantity} to {@link State}. + */ + public static State quantityToState(Optional value) { + return value.flatMap(ChannelTypeUtil::formatQuantity).flatMap(ChannelTypeUtil::parseQuantityType) + .orElse(UnDefType.UNDEF); + } + + /** + * Formats the quantity as "value unit" with the given locale. + * + * @param locale The locale to format with. + * @return An {@link Optional} containing the formatted quantity value or an empty {@link Optional} if formatting + * for the given locale failed. + */ + private static Optional formatQuantity(Quantity quantity) { + double value = quantity.getValue(); + try { + var formatted = NumberFormat.getInstance(Locale.ENGLISH).format(value); + + var unit = quantity.getUnit(); + if (unit.isPresent()) { + formatted = formatted + " " + unit.get(); + } + + return Optional.of(formatted); + } catch (ArithmeticException e) { + logger.warn("Failed to format {}", value, e); + return Optional.empty(); + } + } + + /** + * Parses a previously formatted {@link Quantity} into a {@link State}. + * + * @param value The quantity value formatted as "value unit". + * @return An {@link Optional} containing the parsed {@link State} or an empty {@link Optional} if the quantity + * including unit could not be parsed. + */ + private static Optional parseQuantityType(String value) { + try { + return Optional.of((State) new QuantityType<>(value)); + } catch (IllegalArgumentException e) { + logger.warn("Failed to convert {} to quantity: {}", value, e.getMessage(), e); + return Optional.empty(); + } + } } diff --git a/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/handler/channel/DeviceChannelState.java b/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/handler/channel/DeviceChannelState.java index f517002f297c8..dd472fc635cf7 100644 --- a/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/handler/channel/DeviceChannelState.java +++ b/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/handler/channel/DeviceChannelState.java @@ -35,7 +35,7 @@ * @author Björn Lange - Initial contribution * @author Benjamin Bolte - Add pre-heat finished, plate step, door state, door alarm and info state channel and map * signal flags from API - * @author Björn Lange - Add elapsed time channel, dish warmer and robotic vacuum cleaner thing + * @author Björn Lange - Add elapsed time channel, dish warmer and robotic vacuum cleaner thing, eco feedback */ @NonNullByDefault public final class DeviceChannelState { @@ -185,6 +185,14 @@ public State getSpinningSpeedRaw() { return ChannelTypeUtil.intToState(device.getSpinningSpeedRaw()); } + public State getCurrentWaterConsumption() { + return ChannelTypeUtil.quantityToState(device.getCurrentWaterConsumption()); + } + + public State getCurrentEnergyConsumption() { + return ChannelTypeUtil.quantityToState(device.getCurrentEnergyConsumption()); + } + public State getBatteryLevel() { return ChannelTypeUtil.intToState(device.getBatteryLevel()); } diff --git a/bundles/org.openhab.binding.mielecloud/src/test/java/org/openhab/binding/mielecloud/internal/handler/channel/ChannelTypeUtilTest.java b/bundles/org.openhab.binding.mielecloud/src/test/java/org/openhab/binding/mielecloud/internal/handler/channel/ChannelTypeUtilTest.java new file mode 100644 index 0000000000000..70f5a28b7b8ce --- /dev/null +++ b/bundles/org.openhab.binding.mielecloud/src/test/java/org/openhab/binding/mielecloud/internal/handler/channel/ChannelTypeUtilTest.java @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2010-2023 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.mielecloud.internal.handler.channel; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Optional; +import java.util.stream.Stream; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.openhab.binding.mielecloud.internal.webservice.api.Quantity; +import org.openhab.core.library.types.QuantityType; +import org.openhab.core.library.unit.Units; +import org.openhab.core.types.State; +import org.openhab.core.types.UnDefType; + +/** + * @author Björn Lange - Initial contribution + */ +@NonNullByDefault +public class ChannelTypeUtilTest { + private static Stream quantityToStateConversionArguments() { + return Stream.of(Arguments.of(Optional.empty(), UnDefType.UNDEF), + Arguments.of(Optional.of(new Quantity(10.0, "Gold")), UnDefType.UNDEF), + Arguments.of(Optional.of(new Quantity(3.0, null)), new QuantityType<>(3.0, Units.ONE)), + Arguments.of(Optional.of(new Quantity(1.0 / 3.0, "l")), new QuantityType<>(0.333, Units.LITRE)), + Arguments.of(Optional.of(new Quantity(20.123, "kWh")), new QuantityType<>(20.123, Units.KILOWATT_HOUR)), + Arguments.of(Optional.of(new Quantity(0.5, "l")), new QuantityType<>(0.5, Units.LITRE))); + } + + @ParameterizedTest + @MethodSource("quantityToStateConversionArguments") + void quantityCanBeConvertedToState(Optional input, State expected) { + // when: + var state = ChannelTypeUtil.quantityToState(input); + + // then: + assertEquals(expected, state); + } +} From 598e2e0bf0c31cc0d25e2d02f0fa00dd184fead4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Lange?= Date: Mon, 20 Feb 2023 06:59:51 +0100 Subject: [PATCH 04/13] Add eco feedback channels to devices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Björn Lange --- bundles/org.openhab.binding.mielecloud/README.md | 9 +++++++++ .../internal/MieleCloudBindingConstants.java | 4 +++- .../handler/DishwasherDeviceThingHandler.java | 4 +++- .../handler/DryerDeviceThingHandler.java | 3 ++- .../handler/WashingDeviceThingHandler.java | 4 +++- .../resources/OH-INF/i18n/mielecloud.properties | 6 ++++++ .../OH-INF/i18n/mielecloud_de.properties | 6 ++++++ .../main/resources/OH-INF/thing/channelTypes.xml | 16 ++++++++++++++++ .../resources/OH-INF/thing/dishwasherDevice.xml | 2 ++ .../main/resources/OH-INF/thing/dryerDevice.xml | 1 + .../main/resources/OH-INF/thing/washerDryer.xml | 2 ++ .../resources/OH-INF/thing/washingMachine.xml | 2 ++ .../DishwasherDeviceThingHandlerTest.java | 13 ++++++++++++- .../handler/DryerDeviceThingHandlerTest.java | 10 +++++++++- .../handler/WashingDeviceThingHandlerTest.java | 12 +++++++++++- 15 files changed, 87 insertions(+), 7 deletions(-) diff --git a/bundles/org.openhab.binding.mielecloud/README.md b/bundles/org.openhab.binding.mielecloud/README.md index eca75279f5b09..8e8e42e21a7f6 100644 --- a/bundles/org.openhab.binding.mielecloud/README.md +++ b/bundles/org.openhab.binding.mielecloud/README.md @@ -151,6 +151,8 @@ Channel ID and channel type ID match unless noted. | plate_power_step_raw | Number | The raw power level of the heating plate. | Yes | | door_state | Switch | Indicates if the door of the device is open. | Yes | | door_alarm | Switch | Indicates if the door alarm of the device is active. | Yes | +| water_consumption_current | Number | The amount of water used by the current running program up to the present moment. | Yes | +| energy_consumption_current | Number | The amount of energy used by the current running program up to the present moment. | Yes | | battery_level | Number | The battery level of the robotic vacuum cleaner. | Yes | ### Coffee System @@ -215,6 +217,8 @@ Channel ID and channel type ID match unless noted. - error_state - info_state - door_state +- water_consumption_current +- energy_consumption_current ### Tumble Dryer @@ -242,6 +246,7 @@ Channel ID and channel type ID match unless noted. - light_switch - light_can_be_controlled - door_state +- energy_consumption_current ### Freezer @@ -387,6 +392,8 @@ Channel ID and channel type ID match unless noted. - light_switch - light_can_be_controlled - door_state +- water_consumption_current +- energy_consumption_current ### Washing Machine @@ -415,6 +422,8 @@ Channel ID and channel type ID match unless noted. - light_switch - light_can_be_controlled - door_state +- water_consumption_current +- energy_consumption_current ### Wine Storage diff --git a/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/MieleCloudBindingConstants.java b/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/MieleCloudBindingConstants.java index cbb3f8810699e..5e9549afdf186 100644 --- a/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/MieleCloudBindingConstants.java +++ b/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/MieleCloudBindingConstants.java @@ -23,7 +23,7 @@ * @author Björn Lange - Added locale config parameter, added i18n key collection * @author Benjamin Bolte - Add pre-heat finished and plate step channels, door state and door alarm channels, info * state channel and map signal flags from API - * @author Björn Lange - Add elapsed time channel, dish warmer thing, removed e-mail validation + * @author Björn Lange - Add elapsed time channel, dish warmer thing, removed e-mail validation, add eco feedback */ @NonNullByDefault public final class MieleCloudBindingConstants { @@ -214,6 +214,8 @@ private Channels() { public static final String PLATE_6_POWER_STEP_RAW = "plate_6_power_step_raw"; public static final String DOOR_STATE = "door_state"; public static final String DOOR_ALARM = "door_alarm"; + public static final String WATER_CONSUMPTION_CURRENT = "water_consumption_current"; + public static final String ENERGY_CONSUMPTION_CURRENT = "energy_consumption_current"; public static final String BATTERY_LEVEL = "battery_level"; } diff --git a/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/handler/DishwasherDeviceThingHandler.java b/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/handler/DishwasherDeviceThingHandler.java index 1d5dd0faba589..d210207bce3a9 100644 --- a/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/handler/DishwasherDeviceThingHandler.java +++ b/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/handler/DishwasherDeviceThingHandler.java @@ -26,7 +26,7 @@ * @author Roland Edelhoff - Initial contribution * @author Björn Lange - Add channel state wrappers * @author Benjamin Bolte - Add info state channel and map signal flags from API - * @author Björn Lange - Add elapsed time channel + * @author Björn Lange - Add elapsed time, current water and energy consumption channels */ @NonNullByDefault public class DishwasherDeviceThingHandler extends AbstractMieleThingHandler { @@ -54,6 +54,8 @@ protected void updateDeviceState(DeviceChannelState device) { updateState(channel(ERROR_STATE), device.getErrorState()); updateState(channel(INFO_STATE), device.getInfoState()); updateState(channel(DOOR_STATE), device.getDoorState()); + updateState(channel(WATER_CONSUMPTION_CURRENT), device.getCurrentWaterConsumption()); + updateState(channel(ENERGY_CONSUMPTION_CURRENT), device.getCurrentEnergyConsumption()); } @Override diff --git a/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/handler/DryerDeviceThingHandler.java b/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/handler/DryerDeviceThingHandler.java index a69b2c3c70ded..d78ce68bcfb90 100644 --- a/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/handler/DryerDeviceThingHandler.java +++ b/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/handler/DryerDeviceThingHandler.java @@ -26,7 +26,7 @@ * @author Roland Edelhoff - Initial contribution * @author Björn Lange - Add channel state wrappers * @author Benjamin Bolte - Add info state channel and map signal flags from API - * @author Björn Lange - Add elapsed time channel + * @author Björn Lange - Add elapsed time, current water and energy consumption channels */ @NonNullByDefault public class DryerDeviceThingHandler extends AbstractMieleThingHandler { @@ -57,6 +57,7 @@ protected void updateDeviceState(DeviceChannelState device) { updateState(channel(INFO_STATE), device.getInfoState()); updateState(channel(LIGHT_SWITCH), device.getLightSwitch()); updateState(channel(DOOR_STATE), device.getDoorState()); + updateState(channel(ENERGY_CONSUMPTION_CURRENT), device.getCurrentEnergyConsumption()); } @Override diff --git a/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/handler/WashingDeviceThingHandler.java b/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/handler/WashingDeviceThingHandler.java index 08e05a26d7d8d..6102e0e32c68d 100644 --- a/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/handler/WashingDeviceThingHandler.java +++ b/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/handler/WashingDeviceThingHandler.java @@ -26,7 +26,7 @@ * @author Roland Edelhoff - Initial contribution * @author Björn Lange - Add channel state wrappers * @author Benjamin Bolte - Add info state channel and map signal flags from API - * @author Björn Lange - Add elapsed time channel + * @author Björn Lange - Add elapsed time, current water and energy consumption channels */ @NonNullByDefault public class WashingDeviceThingHandler extends AbstractMieleThingHandler { @@ -58,6 +58,8 @@ protected void updateDeviceState(DeviceChannelState device) { updateState(channel(INFO_STATE), device.getInfoState()); updateState(channel(LIGHT_SWITCH), device.getLightSwitch()); updateState(channel(DOOR_STATE), device.getDoorState()); + updateState(channel(WATER_CONSUMPTION_CURRENT), device.getCurrentWaterConsumption()); + updateState(channel(ENERGY_CONSUMPTION_CURRENT), device.getCurrentEnergyConsumption()); } @Override diff --git a/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/i18n/mielecloud.properties b/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/i18n/mielecloud.properties index e74b7d860a38f..95e138e11558a 100644 --- a/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/i18n/mielecloud.properties +++ b/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/i18n/mielecloud.properties @@ -238,6 +238,12 @@ channel-type.mielecloud.door_state.description=Indicates if the door of the devi channel-type.mielecloud.door_alarm.label=Door Alarm channel-type.mielecloud.door_alarm.description=Indicates if the door alarm of the device is active. +channel-type.mielecloud.water_consumption_current.label=Current Water Consumption +channel-type.mielecloud.water_consumption_current.description=The amount of water used by the current running program up to the present moment. + +channel-type.mielecloud.energy_consumption_current.label=Current Energy Consumption +channel-type.mielecloud.energy_consumption_current.description=The amount of energy used by the current running program up to the present moment. + channel-type.mielecloud.battery_level.label=Battery Level channel-type.mielecloud.battery_level.description=The battery level of the robotic vacuum cleaner. diff --git a/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/i18n/mielecloud_de.properties b/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/i18n/mielecloud_de.properties index ded1ce74cb9c3..b014c65a631c7 100644 --- a/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/i18n/mielecloud_de.properties +++ b/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/i18n/mielecloud_de.properties @@ -238,6 +238,12 @@ channel-type.mielecloud.door_state.description=Gibt an, ob die Tür des Geräts channel-type.mielecloud.door_alarm.label=Türalarm channel-type.mielecloud.door_alarm.description=Gibt an, ob der Türalarm des Geräts aktiv ist. +channel-type.mielecloud.water_consumption_current.label=Aktueller Wasserverbrauch +channel-type.mielecloud.water_consumption_current.description=Durch das derzeit laufende Programm verbrauchte Wasser seit Programmstart. + +channel-type.mielecloud.energy_consumption_current.label=Aktueller Stromverbrauch +channel-type.mielecloud.energy_consumption_current.description=Durch das derzeit laufende Programm verbrauchter Strom seit Programmstart. + channel-type.mielecloud.battery_level.label=Ladezustand channel-type.mielecloud.battery_level.description=Der Ladezustand des Roboter-Staubsaugers. diff --git a/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/channelTypes.xml b/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/channelTypes.xml index e1cb16cca921b..2bf7433bbc44c 100644 --- a/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/channelTypes.xml +++ b/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/channelTypes.xml @@ -438,6 +438,22 @@ + + Number:Water + + @text/channel-type.mielecloud.water_consumption_current.description + Number:Water + + + + + Number:Energy + + @text/channel-type.mielecloud.energy_consumption_current.description + Number:Energy + + + Number diff --git a/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/dishwasherDevice.xml b/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/dishwasherDevice.xml index 2d97427f21bd9..ca118b172fd4c 100644 --- a/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/dishwasherDevice.xml +++ b/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/dishwasherDevice.xml @@ -34,6 +34,8 @@ + + diff --git a/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/dryerDevice.xml b/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/dryerDevice.xml index 0522f0021003d..c11c07c005644 100644 --- a/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/dryerDevice.xml +++ b/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/dryerDevice.xml @@ -38,6 +38,7 @@ + diff --git a/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/washerDryer.xml b/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/washerDryer.xml index 21f21cb0e662b..e32a723aedb06 100644 --- a/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/washerDryer.xml +++ b/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/washerDryer.xml @@ -41,6 +41,8 @@ + + diff --git a/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/washingMachine.xml b/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/washingMachine.xml index 8143ebb70f00f..14cd9fd44ce69 100644 --- a/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/washingMachine.xml +++ b/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/washingMachine.xml @@ -39,6 +39,8 @@ + + diff --git a/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/DishwasherDeviceThingHandlerTest.java b/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/DishwasherDeviceThingHandlerTest.java index ca453fe30f02e..f0b2e18cbce48 100644 --- a/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/DishwasherDeviceThingHandlerTest.java +++ b/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/DishwasherDeviceThingHandlerTest.java @@ -28,15 +28,18 @@ import org.openhab.binding.mielecloud.internal.webservice.api.DeviceState; import org.openhab.binding.mielecloud.internal.webservice.api.PowerStatus; import org.openhab.binding.mielecloud.internal.webservice.api.ProgramStatus; +import org.openhab.binding.mielecloud.internal.webservice.api.Quantity; import org.openhab.binding.mielecloud.internal.webservice.api.json.StateType; import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.OnOffType; +import org.openhab.core.library.types.QuantityType; import org.openhab.core.library.types.StringType; +import org.openhab.core.library.unit.Units; /** * @author Björn Lange - Initial contribution * @author Benjamin Bolte - Add info state channel and map signal flags from API tests - * @author Björn Lange - Add elapsed time channel + * @author Björn Lange - Add elapsed time, current water and energy consumption channels */ @NonNullByDefault public class DishwasherDeviceThingHandlerTest extends AbstractMieleThingHandlerTest { @@ -64,6 +67,8 @@ public void testChannelUpdatesForNullValues() throws Exception { when(deviceState.getStartTime()).thenReturn(Optional.empty()); when(deviceState.getElapsedTime()).thenReturn(Optional.empty()); when(deviceState.getDoorState()).thenReturn(Optional.empty()); + when(deviceState.getCurrentWaterConsumption()).thenReturn(Optional.empty()); + when(deviceState.getCurrentEnergyConsumption()).thenReturn(Optional.empty()); // when: getBridgeHandler().onDeviceStateUpdated(deviceState); @@ -81,6 +86,8 @@ public void testChannelUpdatesForNullValues() throws Exception { assertEquals(NULL_VALUE_STATE, getChannelState(DELAYED_START_TIME)); assertEquals(NULL_VALUE_STATE, getChannelState(PROGRAM_ELAPSED_TIME)); assertEquals(NULL_VALUE_STATE, getChannelState(DOOR_STATE)); + assertEquals(NULL_VALUE_STATE, getChannelState(WATER_CONSUMPTION_CURRENT)); + assertEquals(NULL_VALUE_STATE, getChannelState(ENERGY_CONSUMPTION_CURRENT)); }); } @@ -105,6 +112,8 @@ public void testChannelUpdatesForValidValues() throws Exception { when(deviceState.hasError()).thenReturn(false); when(deviceState.hasInfo()).thenReturn(true); when(deviceState.getDoorState()).thenReturn(Optional.of(true)); + when(deviceState.getCurrentWaterConsumption()).thenReturn(Optional.of(new Quantity(1.0, "l"))); + when(deviceState.getCurrentEnergyConsumption()).thenReturn(Optional.of(new Quantity(2.5, "kWh"))); // when: getBridgeHandler().onDeviceStateUpdated(deviceState); @@ -124,6 +133,8 @@ public void testChannelUpdatesForValidValues() throws Exception { assertEquals(OnOffType.OFF, getChannelState(ERROR_STATE)); assertEquals(OnOffType.ON, getChannelState(INFO_STATE)); assertEquals(OnOffType.ON, getChannelState(DOOR_STATE)); + assertEquals(new QuantityType<>(1.0, Units.LITRE), getChannelState(WATER_CONSUMPTION_CURRENT)); + assertEquals(new QuantityType<>(2.5, Units.KILOWATT_HOUR), getChannelState(ENERGY_CONSUMPTION_CURRENT)); }); } diff --git a/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/DryerDeviceThingHandlerTest.java b/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/DryerDeviceThingHandlerTest.java index c1bb65f9bdd9c..91da2bb37abe7 100644 --- a/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/DryerDeviceThingHandlerTest.java +++ b/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/DryerDeviceThingHandlerTest.java @@ -28,15 +28,18 @@ import org.openhab.binding.mielecloud.internal.webservice.api.DeviceState; import org.openhab.binding.mielecloud.internal.webservice.api.PowerStatus; import org.openhab.binding.mielecloud.internal.webservice.api.ProgramStatus; +import org.openhab.binding.mielecloud.internal.webservice.api.Quantity; import org.openhab.binding.mielecloud.internal.webservice.api.json.StateType; import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.OnOffType; +import org.openhab.core.library.types.QuantityType; import org.openhab.core.library.types.StringType; +import org.openhab.core.library.unit.Units; /** * @author Björn Lange - Initial contribution * @author Benjamin Bolte - Add info state channel and map signal flags from API tests - * @author Björn Lange - Add elapsed time channel + * @author Björn Lange - Add elapsed time, current water and energy consumption channels */ @NonNullByDefault public class DryerDeviceThingHandlerTest extends AbstractMieleThingHandlerTest { @@ -67,6 +70,7 @@ public void testChannelUpdatesForNullValues() throws Exception { when(deviceState.getDryingTargetRaw()).thenReturn(Optional.empty()); when(deviceState.getLightState()).thenReturn(Optional.empty()); when(deviceState.getDoorState()).thenReturn(Optional.empty()); + when(deviceState.getCurrentEnergyConsumption()).thenReturn(Optional.empty()); // when: getBridgeHandler().onDeviceStateUpdated(deviceState); @@ -87,6 +91,8 @@ public void testChannelUpdatesForNullValues() throws Exception { assertEquals(NULL_VALUE_STATE, getChannelState(DRYING_TARGET_RAW)); assertEquals(NULL_VALUE_STATE, getChannelState(LIGHT_SWITCH)); assertEquals(NULL_VALUE_STATE, getChannelState(DOOR_STATE)); + assertEquals(NULL_VALUE_STATE, getChannelState(WATER_CONSUMPTION_CURRENT)); + assertEquals(NULL_VALUE_STATE, getChannelState(ENERGY_CONSUMPTION_CURRENT)); }); } @@ -114,6 +120,7 @@ public void testChannelUpdatesForValidValues() throws Exception { when(deviceState.hasInfo()).thenReturn(true); when(deviceState.getLightState()).thenReturn(Optional.of(false)); when(deviceState.getDoorState()).thenReturn(Optional.of(false)); + when(deviceState.getCurrentEnergyConsumption()).thenReturn(Optional.of(new Quantity(2.5, "Wh"))); // when: getBridgeHandler().onDeviceStateUpdated(deviceState); @@ -136,6 +143,7 @@ public void testChannelUpdatesForValidValues() throws Exception { assertEquals(OnOffType.ON, getChannelState(INFO_STATE)); assertEquals(OnOffType.OFF, getChannelState(LIGHT_SWITCH)); assertEquals(OnOffType.OFF, getChannelState(DOOR_STATE)); + assertEquals(new QuantityType<>(1.5, Units.WATT_HOUR), getChannelState(ENERGY_CONSUMPTION_CURRENT)); }); } diff --git a/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/WashingDeviceThingHandlerTest.java b/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/WashingDeviceThingHandlerTest.java index e495cab3ee7b9..cf071b46eb61e 100644 --- a/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/WashingDeviceThingHandlerTest.java +++ b/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/WashingDeviceThingHandlerTest.java @@ -28,17 +28,19 @@ import org.openhab.binding.mielecloud.internal.webservice.api.DeviceState; import org.openhab.binding.mielecloud.internal.webservice.api.PowerStatus; import org.openhab.binding.mielecloud.internal.webservice.api.ProgramStatus; +import org.openhab.binding.mielecloud.internal.webservice.api.Quantity; import org.openhab.binding.mielecloud.internal.webservice.api.json.StateType; import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.QuantityType; import org.openhab.core.library.types.StringType; import org.openhab.core.library.unit.SIUnits; +import org.openhab.core.library.unit.Units; /** * @author Björn Lange - Initial contribution * @author Benjamin Bolte - Add info state channel and map signal flags from API tests - * @author Björn Lange - Add elapsed time channel + * @author Björn Lange - Add elapsed time, current water and energy consumption channels */ @NonNullByDefault public class WashingDeviceThingHandlerTest extends AbstractMieleThingHandlerTest { @@ -71,6 +73,8 @@ public void testChannelUpdatesForNullValues() throws Exception { when(deviceState.getTargetTemperature(0)).thenReturn(Optional.empty()); when(deviceState.getLightState()).thenReturn(Optional.empty()); when(deviceState.getDoorState()).thenReturn(Optional.empty()); + when(deviceState.getCurrentWaterConsumption()).thenReturn(Optional.empty()); + when(deviceState.getCurrentEnergyConsumption()).thenReturn(Optional.empty()); // when: getBridgeHandler().onDeviceStateUpdated(deviceState); @@ -92,6 +96,8 @@ public void testChannelUpdatesForNullValues() throws Exception { assertEquals(NULL_VALUE_STATE, getChannelState(TEMPERATURE_TARGET)); assertEquals(NULL_VALUE_STATE, getChannelState(LIGHT_SWITCH)); assertEquals(NULL_VALUE_STATE, getChannelState(DOOR_STATE)); + assertEquals(NULL_VALUE_STATE, getChannelState(WATER_CONSUMPTION_CURRENT)); + assertEquals(NULL_VALUE_STATE, getChannelState(ENERGY_CONSUMPTION_CURRENT)); }); } @@ -120,6 +126,8 @@ public void testChannelUpdatesForValidValues() throws Exception { when(deviceState.hasInfo()).thenReturn(true); when(deviceState.getLightState()).thenReturn(Optional.of(false)); when(deviceState.getDoorState()).thenReturn(Optional.of(true)); + when(deviceState.getCurrentWaterConsumption()).thenReturn(Optional.of(new Quantity(0.5, "l"))); + when(deviceState.getCurrentEnergyConsumption()).thenReturn(Optional.of(new Quantity(1.5, "kWh"))); // when: getBridgeHandler().onDeviceStateUpdated(deviceState); @@ -143,6 +151,8 @@ public void testChannelUpdatesForValidValues() throws Exception { assertEquals(OnOffType.ON, getChannelState(INFO_STATE)); assertEquals(OnOffType.OFF, getChannelState(LIGHT_SWITCH)); assertEquals(OnOffType.ON, getChannelState(DOOR_STATE)); + assertEquals(new QuantityType<>(0.5, Units.LITRE), getChannelState(WATER_CONSUMPTION_CURRENT)); + assertEquals(new QuantityType<>(1.5, Units.KILOWATT_HOUR), getChannelState(ENERGY_CONSUMPTION_CURRENT)); }); } From ddf00f070d167b6b481fbb42e6821edd792ada8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Lange?= Date: Tue, 21 Feb 2023 08:29:34 +0100 Subject: [PATCH 05/13] Fix item types and categories MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Björn Lange --- .../main/resources/OH-INF/thing/channelTypes.xml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/channelTypes.xml b/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/channelTypes.xml index 2bf7433bbc44c..c0451fc296caa 100644 --- a/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/channelTypes.xml +++ b/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/channelTypes.xml @@ -439,10 +439,14 @@ - Number:Water + Number:Volume @text/channel-type.mielecloud.water_consumption_current.description - Number:Water + Water + + Measurement + Water + @@ -450,7 +454,11 @@ Number:Energy @text/channel-type.mielecloud.energy_consumption_current.description - Number:Energy + Energy + + Measurement + Energy + From 47b46100ba770138733321e68e656ef3a1a98a82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Lange?= Date: Thu, 23 Feb 2023 08:14:58 +0100 Subject: [PATCH 06/13] Add update instructions for eco feedback channels MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Björn Lange --- .../resources/OH-INF/update/instructions.xml | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/update/instructions.xml diff --git a/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/update/instructions.xml b/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/update/instructions.xml new file mode 100644 index 0000000000000..07d1291a38862 --- /dev/null +++ b/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/update/instructions.xml @@ -0,0 +1,46 @@ + + + + + + + mielecloud:water_consumption_current + + + mielecloud:energy_consumption_current + + + + + + + + mielecloud:energy_consumption_current + + + + + + + + mielecloud:water_consumption_current + + + mielecloud:energy_consumption_current + + + + + + + + mielecloud:water_consumption_current + + + mielecloud:energy_consumption_current + + + + From 6c784158f9474c33b1a8885e72920b1c56cdf5f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Lange?= Date: Thu, 23 Feb 2023 08:17:44 +0100 Subject: [PATCH 07/13] Remove translations for eco feedback channels MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Björn Lange --- .../src/main/resources/OH-INF/i18n/mielecloud_de.properties | 6 ------ 1 file changed, 6 deletions(-) diff --git a/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/i18n/mielecloud_de.properties b/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/i18n/mielecloud_de.properties index b014c65a631c7..ded1ce74cb9c3 100644 --- a/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/i18n/mielecloud_de.properties +++ b/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/i18n/mielecloud_de.properties @@ -238,12 +238,6 @@ channel-type.mielecloud.door_state.description=Gibt an, ob die Tür des Geräts channel-type.mielecloud.door_alarm.label=Türalarm channel-type.mielecloud.door_alarm.description=Gibt an, ob der Türalarm des Geräts aktiv ist. -channel-type.mielecloud.water_consumption_current.label=Aktueller Wasserverbrauch -channel-type.mielecloud.water_consumption_current.description=Durch das derzeit laufende Programm verbrauchte Wasser seit Programmstart. - -channel-type.mielecloud.energy_consumption_current.label=Aktueller Stromverbrauch -channel-type.mielecloud.energy_consumption_current.description=Durch das derzeit laufende Programm verbrauchter Strom seit Programmstart. - channel-type.mielecloud.battery_level.label=Ladezustand channel-type.mielecloud.battery_level.description=Der Ladezustand des Roboter-Staubsaugers. From 79708ab3707c49cd3a1568acf793c619f9ea43d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Lange?= Date: Fri, 24 Feb 2023 08:13:49 +0100 Subject: [PATCH 08/13] thingTypeVersion property prevents unwanted update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Björn Lange --- .../src/main/resources/OH-INF/thing/dishwasherDevice.xml | 1 + .../src/main/resources/OH-INF/thing/dryerDevice.xml | 1 + .../src/main/resources/OH-INF/thing/washerDryer.xml | 1 + .../src/main/resources/OH-INF/thing/washingMachine.xml | 1 + 4 files changed, 4 insertions(+) diff --git a/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/dishwasherDevice.xml b/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/dishwasherDevice.xml index ca118b172fd4c..64fe077e019aa 100644 --- a/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/dishwasherDevice.xml +++ b/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/dishwasherDevice.xml @@ -39,6 +39,7 @@ + 1 Miele diff --git a/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/dryerDevice.xml b/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/dryerDevice.xml index c11c07c005644..6d26b619804b5 100644 --- a/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/dryerDevice.xml +++ b/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/dryerDevice.xml @@ -42,6 +42,7 @@ + 1 Miele diff --git a/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/washerDryer.xml b/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/washerDryer.xml index e32a723aedb06..a9b7895c1a44f 100644 --- a/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/washerDryer.xml +++ b/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/washerDryer.xml @@ -46,6 +46,7 @@ + 1 Miele diff --git a/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/washingMachine.xml b/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/washingMachine.xml index 14cd9fd44ce69..8be636fb3643d 100644 --- a/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/washingMachine.xml +++ b/bundles/org.openhab.binding.mielecloud/src/main/resources/OH-INF/thing/washingMachine.xml @@ -44,6 +44,7 @@ + 1 Miele From 5401eb9bb68a9d6db0757d5367ae4dd443449454 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Lange?= Date: Fri, 24 Mar 2023 10:52:21 +0100 Subject: [PATCH 09/13] Manually specify thingTypeVersion in integration tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Björn Lange --- .../internal/handler/AbstractMieleThingHandlerTest.java | 6 ++++-- .../internal/handler/CoffeeDeviceThingHandlerTest.java | 2 +- .../internal/handler/CoolingDeviceThingHandlerTest.java | 2 +- .../internal/handler/DishWarmerDeviceThingHandlerTest.java | 2 +- .../internal/handler/DishwasherDeviceThingHandlerTest.java | 2 +- .../internal/handler/DryerDeviceThingHandlerTest.java | 2 +- .../internal/handler/HobDeviceThingHandlerTest.java | 2 +- .../internal/handler/HoodDeviceThingHandlerTest.java | 2 +- .../internal/handler/OvenDeviceThingHandlerTest.java | 2 +- .../handler/RoboticVacuumCleanerDeviceThingHandlerTest.java | 3 ++- .../internal/handler/WashingDeviceThingHandlerTest.java | 2 +- .../internal/handler/WineStorageDeviceThingHandlerTest.java | 2 +- 12 files changed, 16 insertions(+), 13 deletions(-) diff --git a/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/AbstractMieleThingHandlerTest.java b/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/AbstractMieleThingHandlerTest.java index 7ed43b57253ca..c29a9f15c3c5a 100644 --- a/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/AbstractMieleThingHandlerTest.java +++ b/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/AbstractMieleThingHandlerTest.java @@ -209,7 +209,8 @@ private void setUpBridge() throws Exception { } protected AbstractMieleThingHandler createThingHandler(ThingTypeUID thingTypeUid, ThingUID thingUid, - Class expectedHandlerClass, String deviceIdentifier) { + Class expectedHandlerClass, String deviceIdentifier, + String thingTypeVersion) { ThingRegistry registry = getThingRegistry(); List channels = createChannelsForThingHandler(thingTypeUid, thingUid); @@ -217,7 +218,8 @@ protected AbstractMieleThingHandler createThingHandler(ThingTypeUID thingTypeUid Thing thing = ThingBuilder.create(thingTypeUid, thingUid) .withConfiguration(new Configuration(Collections .singletonMap(MieleCloudBindingConstants.CONFIG_PARAM_DEVICE_IDENTIFIER, deviceIdentifier))) - .withBridge(getBridge().getUID()).withChannels(channels).withLabel("DA-6996").build(); + .withBridge(getBridge().getUID()).withChannels(channels).withLabel("DA-6996") + .withProperty("thingTypeVersion", thingTypeVersion).build(); assertNotNull(thing); registry.add(thing); diff --git a/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/CoffeeDeviceThingHandlerTest.java b/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/CoffeeDeviceThingHandlerTest.java index fecedc11efe11..d97582c375e2f 100644 --- a/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/CoffeeDeviceThingHandlerTest.java +++ b/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/CoffeeDeviceThingHandlerTest.java @@ -42,7 +42,7 @@ public class CoffeeDeviceThingHandlerTest extends AbstractMieleThingHandlerTest @Override protected AbstractMieleThingHandler setUpThingHandler() { return createThingHandler(MieleCloudBindingConstants.THING_TYPE_COFFEE_SYSTEM, COFFEE_SYSTEM_THING_UID, - CoffeeSystemThingHandler.class, MieleCloudBindingIntegrationTestConstants.SERIAL_NUMBER); + CoffeeSystemThingHandler.class, MieleCloudBindingIntegrationTestConstants.SERIAL_NUMBER, "0"); } @Test diff --git a/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/CoolingDeviceThingHandlerTest.java b/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/CoolingDeviceThingHandlerTest.java index fcb8d41b10458..70024bca1c976 100644 --- a/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/CoolingDeviceThingHandlerTest.java +++ b/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/CoolingDeviceThingHandlerTest.java @@ -45,7 +45,7 @@ public class CoolingDeviceThingHandlerTest extends AbstractMieleThingHandlerTest @Override protected AbstractMieleThingHandler setUpThingHandler() { return createThingHandler(MieleCloudBindingConstants.THING_TYPE_FRIDGE_FREEZER, FRIDGE_FREEZER_DEVICE_THING_UID, - CoolingDeviceThingHandler.class, MieleCloudBindingIntegrationTestConstants.SERIAL_NUMBER); + CoolingDeviceThingHandler.class, MieleCloudBindingIntegrationTestConstants.SERIAL_NUMBER, "0"); } @Test diff --git a/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/DishWarmerDeviceThingHandlerTest.java b/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/DishWarmerDeviceThingHandlerTest.java index 7f9498388482c..ef685835f3b97 100644 --- a/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/DishWarmerDeviceThingHandlerTest.java +++ b/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/DishWarmerDeviceThingHandlerTest.java @@ -42,7 +42,7 @@ public class DishWarmerDeviceThingHandlerTest extends AbstractMieleThingHandlerT protected AbstractMieleThingHandler setUpThingHandler() { return createThingHandler(MieleCloudBindingConstants.THING_TYPE_DISH_WARMER, MieleCloudBindingIntegrationTestConstants.DISH_WARMER_DEVICE_THING_UID, - DishWarmerDeviceThingHandler.class, MieleCloudBindingIntegrationTestConstants.SERIAL_NUMBER); + DishWarmerDeviceThingHandler.class, MieleCloudBindingIntegrationTestConstants.SERIAL_NUMBER, "0"); } @Test diff --git a/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/DishwasherDeviceThingHandlerTest.java b/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/DishwasherDeviceThingHandlerTest.java index f0b2e18cbce48..a4d73edbcabb9 100644 --- a/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/DishwasherDeviceThingHandlerTest.java +++ b/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/DishwasherDeviceThingHandlerTest.java @@ -46,7 +46,7 @@ public class DishwasherDeviceThingHandlerTest extends AbstractMieleThingHandlerT @Override protected AbstractMieleThingHandler setUpThingHandler() { return createThingHandler(MieleCloudBindingConstants.THING_TYPE_DISHWASHER, DISHWASHER_DEVICE_THING_UID, - DishwasherDeviceThingHandler.class, MieleCloudBindingIntegrationTestConstants.SERIAL_NUMBER); + DishwasherDeviceThingHandler.class, MieleCloudBindingIntegrationTestConstants.SERIAL_NUMBER, "1"); } @Test diff --git a/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/DryerDeviceThingHandlerTest.java b/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/DryerDeviceThingHandlerTest.java index 91da2bb37abe7..d14b2e9d572c4 100644 --- a/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/DryerDeviceThingHandlerTest.java +++ b/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/DryerDeviceThingHandlerTest.java @@ -46,7 +46,7 @@ public class DryerDeviceThingHandlerTest extends AbstractMieleThingHandlerTest { @Override protected AbstractMieleThingHandler setUpThingHandler() { return createThingHandler(MieleCloudBindingConstants.THING_TYPE_DRYER, DRYER_DEVICE_THING_UID, - DryerDeviceThingHandler.class, MieleCloudBindingIntegrationTestConstants.SERIAL_NUMBER); + DryerDeviceThingHandler.class, MieleCloudBindingIntegrationTestConstants.SERIAL_NUMBER, "1"); } @Test diff --git a/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/HobDeviceThingHandlerTest.java b/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/HobDeviceThingHandlerTest.java index 4a57cc474e9bc..007ddd08cc5b3 100644 --- a/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/HobDeviceThingHandlerTest.java +++ b/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/HobDeviceThingHandlerTest.java @@ -40,7 +40,7 @@ public class HobDeviceThingHandlerTest extends AbstractMieleThingHandlerTest { @Override protected AbstractMieleThingHandler setUpThingHandler() { return createThingHandler(MieleCloudBindingConstants.THING_TYPE_HOB, HOB_DEVICE_THING_UID, - HobDeviceThingHandler.class, MieleCloudBindingIntegrationTestConstants.SERIAL_NUMBER); + HobDeviceThingHandler.class, MieleCloudBindingIntegrationTestConstants.SERIAL_NUMBER, "0"); } @Test diff --git a/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/HoodDeviceThingHandlerTest.java b/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/HoodDeviceThingHandlerTest.java index ef87d664860cc..ecef8bfde7b1d 100644 --- a/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/HoodDeviceThingHandlerTest.java +++ b/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/HoodDeviceThingHandlerTest.java @@ -40,7 +40,7 @@ public class HoodDeviceThingHandlerTest extends AbstractMieleThingHandlerTest { @Override protected AbstractMieleThingHandler setUpThingHandler() { return createThingHandler(MieleCloudBindingConstants.THING_TYPE_HOOD, HOOD_DEVICE_THING_UID, - HoodDeviceThingHandler.class, MieleCloudBindingIntegrationTestConstants.SERIAL_NUMBER); + HoodDeviceThingHandler.class, MieleCloudBindingIntegrationTestConstants.SERIAL_NUMBER, "0"); } @Test diff --git a/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/OvenDeviceThingHandlerTest.java b/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/OvenDeviceThingHandlerTest.java index 762483af7babb..beaa6a33b760c 100644 --- a/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/OvenDeviceThingHandlerTest.java +++ b/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/OvenDeviceThingHandlerTest.java @@ -46,7 +46,7 @@ public class OvenDeviceThingHandlerTest extends AbstractMieleThingHandlerTest { @Override protected AbstractMieleThingHandler setUpThingHandler() { return createThingHandler(MieleCloudBindingConstants.THING_TYPE_OVEN, OVEN_DEVICE_THING_UID, - OvenDeviceThingHandler.class, MieleCloudBindingIntegrationTestConstants.SERIAL_NUMBER); + OvenDeviceThingHandler.class, MieleCloudBindingIntegrationTestConstants.SERIAL_NUMBER, "0"); } @Test diff --git a/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/RoboticVacuumCleanerDeviceThingHandlerTest.java b/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/RoboticVacuumCleanerDeviceThingHandlerTest.java index 23a74a9e72ff6..f63bea755eaea 100644 --- a/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/RoboticVacuumCleanerDeviceThingHandlerTest.java +++ b/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/RoboticVacuumCleanerDeviceThingHandlerTest.java @@ -41,7 +41,8 @@ public class RoboticVacuumCleanerDeviceThingHandlerTest extends AbstractMieleThi protected AbstractMieleThingHandler setUpThingHandler() { return createThingHandler(MieleCloudBindingConstants.THING_TYPE_ROBOTIC_VACUUM_CLEANER, MieleCloudBindingIntegrationTestConstants.ROBOTIC_VACUUM_CLEANER_THING_UID, - RoboticVacuumCleanerDeviceThingHandler.class, MieleCloudBindingIntegrationTestConstants.SERIAL_NUMBER); + RoboticVacuumCleanerDeviceThingHandler.class, MieleCloudBindingIntegrationTestConstants.SERIAL_NUMBER, + "0"); } @Test diff --git a/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/WashingDeviceThingHandlerTest.java b/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/WashingDeviceThingHandlerTest.java index cf071b46eb61e..176a2b259b209 100644 --- a/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/WashingDeviceThingHandlerTest.java +++ b/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/WashingDeviceThingHandlerTest.java @@ -48,7 +48,7 @@ public class WashingDeviceThingHandlerTest extends AbstractMieleThingHandlerTest @Override protected AbstractMieleThingHandler setUpThingHandler() { return createThingHandler(MieleCloudBindingConstants.THING_TYPE_WASHING_MACHINE, WASHING_MACHINE_THING_UID, - WashingDeviceThingHandler.class, MieleCloudBindingIntegrationTestConstants.SERIAL_NUMBER); + WashingDeviceThingHandler.class, MieleCloudBindingIntegrationTestConstants.SERIAL_NUMBER, "1"); } @Test diff --git a/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/WineStorageDeviceThingHandlerTest.java b/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/WineStorageDeviceThingHandlerTest.java index b6540ba0e7d55..8cfad8cf5b3e9 100644 --- a/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/WineStorageDeviceThingHandlerTest.java +++ b/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/WineStorageDeviceThingHandlerTest.java @@ -43,7 +43,7 @@ public class WineStorageDeviceThingHandlerTest extends AbstractMieleThingHandler @Override protected AbstractMieleThingHandler setUpThingHandler() { return createThingHandler(MieleCloudBindingConstants.THING_TYPE_WINE_STORAGE, WINE_STORAGE_DEVICE_THING_UID, - WineStorageDeviceThingHandler.class, MieleCloudBindingIntegrationTestConstants.SERIAL_NUMBER); + WineStorageDeviceThingHandler.class, MieleCloudBindingIntegrationTestConstants.SERIAL_NUMBER, "0"); } @Test From c0126dbe02acda204ea3b8ff3731505df77e00b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Lange?= Date: Fri, 24 Mar 2023 11:05:29 +0100 Subject: [PATCH 10/13] Fix integration test for dryer device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Björn Lange --- .../internal/handler/DryerDeviceThingHandlerTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/DryerDeviceThingHandlerTest.java b/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/DryerDeviceThingHandlerTest.java index d14b2e9d572c4..e26269004166e 100644 --- a/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/DryerDeviceThingHandlerTest.java +++ b/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/DryerDeviceThingHandlerTest.java @@ -143,7 +143,7 @@ public void testChannelUpdatesForValidValues() throws Exception { assertEquals(OnOffType.ON, getChannelState(INFO_STATE)); assertEquals(OnOffType.OFF, getChannelState(LIGHT_SWITCH)); assertEquals(OnOffType.OFF, getChannelState(DOOR_STATE)); - assertEquals(new QuantityType<>(1.5, Units.WATT_HOUR), getChannelState(ENERGY_CONSUMPTION_CURRENT)); + assertEquals(new QuantityType<>(2.5, Units.WATT_HOUR), getChannelState(ENERGY_CONSUMPTION_CURRENT)); }); } From b4f899dd7cece0dee1dc3671d01ca30f8d448872 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Lange?= Date: Fri, 24 Mar 2023 11:10:58 +0100 Subject: [PATCH 11/13] Dryer device has no water consumption MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Björn Lange --- .../mielecloud/internal/handler/DryerDeviceThingHandlerTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/DryerDeviceThingHandlerTest.java b/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/DryerDeviceThingHandlerTest.java index e26269004166e..c7069ff784ebf 100644 --- a/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/DryerDeviceThingHandlerTest.java +++ b/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/DryerDeviceThingHandlerTest.java @@ -91,7 +91,6 @@ public void testChannelUpdatesForNullValues() throws Exception { assertEquals(NULL_VALUE_STATE, getChannelState(DRYING_TARGET_RAW)); assertEquals(NULL_VALUE_STATE, getChannelState(LIGHT_SWITCH)); assertEquals(NULL_VALUE_STATE, getChannelState(DOOR_STATE)); - assertEquals(NULL_VALUE_STATE, getChannelState(WATER_CONSUMPTION_CURRENT)); assertEquals(NULL_VALUE_STATE, getChannelState(ENERGY_CONSUMPTION_CURRENT)); }); } From 1cf191a601b772a67bab39d013a24e2944843630 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Lange?= Date: Fri, 24 Mar 2023 11:15:58 +0100 Subject: [PATCH 12/13] Manually set thingTypeVersion in handler factory test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Björn Lange --- .../handler/MieleHandlerFactoryTest.java | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/MieleHandlerFactoryTest.java b/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/MieleHandlerFactoryTest.java index 61b810142e1c5..ac7ed386a7451 100644 --- a/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/MieleHandlerFactoryTest.java +++ b/itests/org.openhab.binding.mielecloud.tests/src/main/java/org/openhab/binding/mielecloud/internal/handler/MieleHandlerFactoryTest.java @@ -184,7 +184,7 @@ private void verifyHandlerCreation(MieleWebservice webservice, Thing thing, } private void testHandlerCanBeCreatedForMieleDevice(ThingTypeUID thingTypeUid, ThingUID thingUid, String label, - Class expectedHandlerClass) + Class expectedHandlerClass, String thingTypeVersion) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { // given: MieleWebservice webservice = mock(MieleWebservice.class); @@ -196,7 +196,7 @@ private void testHandlerCanBeCreatedForMieleDevice(ThingTypeUID thingTypeUid, Th Thing device = ThingBuilder.create(thingTypeUid, thingUid) .withConfiguration(new Configuration(Collections .singletonMap(MieleCloudBindingConstants.CONFIG_PARAM_DEVICE_IDENTIFIER, DEVICE_IDENTIFIER))) - .withLabel(label).build(); + .withLabel(label).withProperty("thingTypeVersion", thingTypeVersion).build(); assertNotNull(device); verifyHandlerCreation(webservice, device, expectedHandlerClass); @@ -227,77 +227,77 @@ public void testHandlerCanBeCreatedForGenesisBridgeWithEmptyConfiguration() thro public void testHandlerCanBeCreatedForWashingDevice() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { testHandlerCanBeCreatedForMieleDevice(MieleCloudBindingConstants.THING_TYPE_WASHING_MACHINE, - WASHING_MACHINE_TYPE, "DA-6996", WashingDeviceThingHandler.class); + WASHING_MACHINE_TYPE, "DA-6996", WashingDeviceThingHandler.class, "1"); } @Test public void testHandlerCanBeCreatedForOvenDevice() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { testHandlerCanBeCreatedForMieleDevice(MieleCloudBindingConstants.THING_TYPE_OVEN, OVEN_DEVICE_TYPE, "OV-6887", - OvenDeviceThingHandler.class); + OvenDeviceThingHandler.class, "0"); } @Test public void testHandlerCanBeCreatedForHobDevice() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { testHandlerCanBeCreatedForMieleDevice(MieleCloudBindingConstants.THING_TYPE_HOB, HOB_DEVICE_TYPE, "HB-3887", - HobDeviceThingHandler.class); + HobDeviceThingHandler.class, "0"); } @Test public void testHandlerCanBeCreatedForFridgeFreezerDevice() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { testHandlerCanBeCreatedForMieleDevice(MieleCloudBindingConstants.THING_TYPE_FRIDGE_FREEZER, - FRIDGE_FREEZER_DEVICE_TYPE, "CD-6097", CoolingDeviceThingHandler.class); + FRIDGE_FREEZER_DEVICE_TYPE, "CD-6097", CoolingDeviceThingHandler.class, "0"); } @Test public void testHandlerCanBeCreatedForHoodDevice() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { testHandlerCanBeCreatedForMieleDevice(MieleCloudBindingConstants.THING_TYPE_HOOD, HOOD_DEVICE_TYPE, "HD-2097", - HoodDeviceThingHandler.class); + HoodDeviceThingHandler.class, "0"); } @Test public void testHandlerCanBeCreatedForCoffeeDevice() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { testHandlerCanBeCreatedForMieleDevice(MieleCloudBindingConstants.THING_TYPE_COFFEE_SYSTEM, COFFEE_DEVICE_TYPE, - "DA-6997", CoffeeSystemThingHandler.class); + "DA-6997", CoffeeSystemThingHandler.class, "0"); } @Test public void testHandlerCanBeCreatedForWineStorageDevice() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { testHandlerCanBeCreatedForMieleDevice(MieleCloudBindingConstants.THING_TYPE_WINE_STORAGE, - WINE_STORAGE_DEVICE_TYPE, "WS-6907", WineStorageDeviceThingHandler.class); + WINE_STORAGE_DEVICE_TYPE, "WS-6907", WineStorageDeviceThingHandler.class, "0"); } @Test public void testHandlerCanBeCreatedForDryerDevice() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { testHandlerCanBeCreatedForMieleDevice(MieleCloudBindingConstants.THING_TYPE_DRYER, DRYER_DEVICE_TYPE, "DR-0907", - DryerDeviceThingHandler.class); + DryerDeviceThingHandler.class, "1"); } @Test public void testHandlerCanBeCreatedForDishwasherDevice() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { testHandlerCanBeCreatedForMieleDevice(MieleCloudBindingConstants.THING_TYPE_DISHWASHER, DISHWASHER_DEVICE_TYPE, - "DR-0907", DishwasherDeviceThingHandler.class); + "DR-0907", DishwasherDeviceThingHandler.class, "1"); } @Test public void testHandlerCanBeCreatedForDishWarmerDevice() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { testHandlerCanBeCreatedForMieleDevice(MieleCloudBindingConstants.THING_TYPE_DISH_WARMER, - DISH_WARMER_DEVICE_TYPE, "DW-0907", DishWarmerDeviceThingHandler.class); + DISH_WARMER_DEVICE_TYPE, "DW-0907", DishWarmerDeviceThingHandler.class, "0"); } @Test public void testHandlerCanBeCreatedForRoboticVacuumCleanerDevice() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { testHandlerCanBeCreatedForMieleDevice(MieleCloudBindingConstants.THING_TYPE_ROBOTIC_VACUUM_CLEANER, - ROBOTIC_VACUUM_CLEANER_DEVICE_TYPE, "RVC-0907", RoboticVacuumCleanerDeviceThingHandler.class); + ROBOTIC_VACUUM_CLEANER_DEVICE_TYPE, "RVC-0907", RoboticVacuumCleanerDeviceThingHandler.class, "0"); } /** From 49b30b2c275b0ad64bc875762d4128a69e71e65b Mon Sep 17 00:00:00 2001 From: Jacob Laursen Date: Fri, 24 Mar 2023 23:04:47 +0100 Subject: [PATCH 13/13] Fix checkstyle warning Signed-off-by: Jacob Laursen --- .../internal/handler/channel/ChannelTypeUtil.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/handler/channel/ChannelTypeUtil.java b/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/handler/channel/ChannelTypeUtil.java index 7d323dd056bd6..a1a50d28a71a4 100644 --- a/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/handler/channel/ChannelTypeUtil.java +++ b/bundles/org.openhab.binding.mielecloud/src/main/java/org/openhab/binding/mielecloud/internal/handler/channel/ChannelTypeUtil.java @@ -36,7 +36,7 @@ */ @NonNullByDefault public final class ChannelTypeUtil { - private static final Logger logger = LoggerFactory.getLogger(ChannelTypeUtil.class); + private static final Logger LOGGER = LoggerFactory.getLogger(ChannelTypeUtil.class); private ChannelTypeUtil() { throw new IllegalStateException("ChannelTypeUtil cannot be instantiated."); @@ -106,7 +106,7 @@ private static Optional formatQuantity(Quantity quantity) { return Optional.of(formatted); } catch (ArithmeticException e) { - logger.warn("Failed to format {}", value, e); + LOGGER.warn("Failed to format {}", value, e); return Optional.empty(); } } @@ -122,7 +122,7 @@ private static Optional parseQuantityType(String value) { try { return Optional.of((State) new QuantityType<>(value)); } catch (IllegalArgumentException e) { - logger.warn("Failed to convert {} to quantity: {}", value, e.getMessage(), e); + LOGGER.warn("Failed to convert {} to quantity: {}", value, e.getMessage(), e); return Optional.empty(); } }