mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 15:11:59 +01:00
[mielecloud] Add channels energy and water consumption (#14456)
* Add POJOs for ecoFeedback from Miele REST API * DeviceState offers water and energy consumption * Convert Quantity to State for channel population * Add eco feedback channels to devices * Fix item types and categories * Add update instructions for eco feedback channels Signed-off-by: Björn Lange <bjoern.lange@itemis.de>
This commit is contained in:
parent
983efd76ea
commit
fbcb412353
@ -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
|
||||
|
||||
|
@ -23,7 +23,7 @@ import org.openhab.core.thing.ThingTypeUID;
|
||||
* @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 @@ public final class MieleCloudBindingConstants {
|
||||
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";
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ import org.openhab.core.thing.Thing;
|
||||
* @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 @@ public class DishwasherDeviceThingHandler extends AbstractMieleThingHandler {
|
||||
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
|
||||
|
@ -26,7 +26,7 @@ import org.openhab.core.thing.Thing;
|
||||
* @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 @@ public class DryerDeviceThingHandler extends AbstractMieleThingHandler {
|
||||
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
|
||||
|
@ -26,7 +26,7 @@ import org.openhab.core.thing.Thing;
|
||||
* @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 @@ public class WashingDeviceThingHandler extends AbstractMieleThingHandler {
|
||||
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
|
||||
|
@ -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.types.StringType;
|
||||
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 @@ import org.openhab.core.types.UnDefType;
|
||||
*/
|
||||
@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 final class ChannelTypeUtil {
|
||||
// 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<Quantity> 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<String> 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<State> 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ import org.openhab.core.types.State;
|
||||
* @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 final class DeviceChannelState {
|
||||
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());
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import org.openhab.binding.mielecloud.internal.webservice.api.json.Device;
|
||||
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 @@ import org.openhab.binding.mielecloud.internal.webservice.api.json.VentilationSt
|
||||
* @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 class DeviceState {
|
||||
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<Quantity> 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<Quantity> 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.
|
||||
*
|
||||
|
@ -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<String> unit;
|
||||
|
||||
public Quantity(double value, @Nullable String unit) {
|
||||
this.value = value;
|
||||
this.unit = Optional.ofNullable(unit);
|
||||
}
|
||||
|
||||
public double getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public Optional<String> 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 + "]";
|
||||
}
|
||||
}
|
@ -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<WaterConsumption> getCurrentWaterConsumption() {
|
||||
return Optional.ofNullable(currentWaterConsumption);
|
||||
}
|
||||
|
||||
public Optional<EnergyConsumption> getCurrentEnergyConsumption() {
|
||||
return Optional.ofNullable(currentEnergyConsumption);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the relative water usage for the selected program from 0 to 1.
|
||||
*/
|
||||
public Optional<Double> getWaterForecast() {
|
||||
return Optional.ofNullable(waterForecast);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the relative energy usage for the selected program from 0 to 1.
|
||||
*/
|
||||
public Optional<Double> 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
|
||||
+ "]";
|
||||
}
|
||||
}
|
@ -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<String> getUnit() {
|
||||
return Optional.ofNullable(unit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the amount of energy.
|
||||
*/
|
||||
public Optional<Double> 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 + "]";
|
||||
}
|
||||
}
|
@ -25,7 +25,7 @@ import org.eclipse.jdt.annotation.Nullable;
|
||||
*
|
||||
* @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> plateStep = null;
|
||||
@Nullable
|
||||
private EcoFeedback ecoFeedback;
|
||||
@Nullable
|
||||
private Integer batteryLevel;
|
||||
|
||||
public Optional<Status> getStatus() {
|
||||
@ -189,6 +191,10 @@ public class State {
|
||||
return Collections.unmodifiableList(plateStep);
|
||||
}
|
||||
|
||||
public Optional<EcoFeedback> getEcoFeedback() {
|
||||
return Optional.ofNullable(ecoFeedback);
|
||||
}
|
||||
|
||||
public Optional<Integer> getBatteryLevel() {
|
||||
return Optional.ofNullable(batteryLevel);
|
||||
}
|
||||
@ -197,7 +203,7 @@ public class State {
|
||||
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 class State {
|
||||
&& 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 class State {
|
||||
+ ", 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 + "]";
|
||||
}
|
||||
}
|
||||
|
@ -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<String> getUnit() {
|
||||
return Optional.ofNullable(unit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the amount of water.
|
||||
*/
|
||||
public Optional<Double> 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 + "]";
|
||||
}
|
||||
}
|
@ -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.
|
||||
|
||||
|
@ -438,6 +438,30 @@
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="water_consumption_current">
|
||||
<item-type>Number:Volume</item-type>
|
||||
<label>@text/channel-type.mielecloud.water_consumption_current.label</label>
|
||||
<description>@text/channel-type.mielecloud.water_consumption_current.description</description>
|
||||
<category>Water</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Water</tag>
|
||||
</tags>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="energy_consumption_current">
|
||||
<item-type>Number:Energy</item-type>
|
||||
<label>@text/channel-type.mielecloud.energy_consumption_current.label</label>
|
||||
<description>@text/channel-type.mielecloud.energy_consumption_current.description</description>
|
||||
<category>Energy</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>Energy</tag>
|
||||
</tags>
|
||||
<state pattern="%.1f %unit%" readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="battery_level">
|
||||
<item-type>Number</item-type>
|
||||
<label>@text/channel-type.mielecloud.battery_level.label</label>
|
||||
|
@ -34,9 +34,12 @@
|
||||
<channel id="error_state" typeId="error_state"/>
|
||||
<channel id="info_state" typeId="info_state"/>
|
||||
<channel id="door_state" typeId="door_state"/>
|
||||
<channel id="water_consumption_current" typeId="water_consumption_current"/>
|
||||
<channel id="energy_consumption_current" typeId="energy_consumption_current"/>
|
||||
</channels>
|
||||
|
||||
<properties>
|
||||
<property name="thingTypeVersion">1</property>
|
||||
<property name="vendor">Miele</property>
|
||||
</properties>
|
||||
|
||||
|
@ -38,9 +38,11 @@
|
||||
<channel id="light_switch" typeId="light_switch"/>
|
||||
<channel id="light_can_be_controlled" typeId="light_can_be_controlled"/>
|
||||
<channel id="door_state" typeId="door_state"/>
|
||||
<channel id="energy_consumption_current" typeId="energy_consumption_current"/>
|
||||
</channels>
|
||||
|
||||
<properties>
|
||||
<property name="thingTypeVersion">1</property>
|
||||
<property name="vendor">Miele</property>
|
||||
</properties>
|
||||
|
||||
|
@ -41,9 +41,12 @@
|
||||
<channel id="light_switch" typeId="light_switch"/>
|
||||
<channel id="light_can_be_controlled" typeId="light_can_be_controlled"/>
|
||||
<channel id="door_state" typeId="door_state"/>
|
||||
<channel id="water_consumption_current" typeId="water_consumption_current"/>
|
||||
<channel id="energy_consumption_current" typeId="energy_consumption_current"/>
|
||||
</channels>
|
||||
|
||||
<properties>
|
||||
<property name="thingTypeVersion">1</property>
|
||||
<property name="vendor">Miele</property>
|
||||
</properties>
|
||||
|
||||
|
@ -39,9 +39,12 @@
|
||||
<channel id="light_switch" typeId="light_switch"/>
|
||||
<channel id="light_can_be_controlled" typeId="light_can_be_controlled"/>
|
||||
<channel id="door_state" typeId="door_state"/>
|
||||
<channel id="water_consumption_current" typeId="water_consumption_current"/>
|
||||
<channel id="energy_consumption_current" typeId="energy_consumption_current"/>
|
||||
</channels>
|
||||
|
||||
<properties>
|
||||
<property name="thingTypeVersion">1</property>
|
||||
<property name="vendor">Miele</property>
|
||||
</properties>
|
||||
|
||||
|
@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<update:update-descriptions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:update="https://openhab.org/schemas/update-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/update-description/v1.0.0 https://openhab.org/schemas/update-description-1.0.0.xsd">
|
||||
|
||||
<thing-type uid="mielecloud:dishwasher">
|
||||
<instruction-set targetVersion="1">
|
||||
<add-channel id="water_consumption_current">
|
||||
<type>mielecloud:water_consumption_current</type>
|
||||
</add-channel>
|
||||
<add-channel id="energy_consumption_current">
|
||||
<type>mielecloud:energy_consumption_current</type>
|
||||
</add-channel>
|
||||
</instruction-set>
|
||||
</thing-type>
|
||||
|
||||
<thing-type uid="mielecloud:dryer">
|
||||
<instruction-set targetVersion="1">
|
||||
<add-channel id="energy_consumption_current">
|
||||
<type>mielecloud:energy_consumption_current</type>
|
||||
</add-channel>
|
||||
</instruction-set>
|
||||
</thing-type>
|
||||
|
||||
<thing-type uid="mielecloud:washer_dryer">
|
||||
<instruction-set targetVersion="1">
|
||||
<add-channel id="water_consumption_current">
|
||||
<type>mielecloud:water_consumption_current</type>
|
||||
</add-channel>
|
||||
<add-channel id="energy_consumption_current">
|
||||
<type>mielecloud:energy_consumption_current</type>
|
||||
</add-channel>
|
||||
</instruction-set>
|
||||
</thing-type>
|
||||
|
||||
<thing-type uid="mielecloud:washing_machine">
|
||||
<instruction-set targetVersion="1">
|
||||
<add-channel id="water_consumption_current">
|
||||
<type>mielecloud:water_consumption_current</type>
|
||||
</add-channel>
|
||||
<add-channel id="energy_consumption_current">
|
||||
<type>mielecloud:energy_consumption_current</type>
|
||||
</add-channel>
|
||||
</instruction-set>
|
||||
</thing-type>
|
||||
</update:update-descriptions>
|
@ -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<Arguments> 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<Quantity> input, State expected) {
|
||||
// when:
|
||||
var state = ChannelTypeUtil.quantityToState(input);
|
||||
|
||||
// then:
|
||||
assertEquals(expected, state);
|
||||
}
|
||||
}
|
@ -26,6 +26,8 @@ import org.openhab.binding.mielecloud.internal.webservice.api.json.Device;
|
||||
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.Status;
|
||||
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 class DeviceStateTest {
|
||||
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<Quantity> 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<Quantity> 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<Quantity> 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<Quantity> 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<Quantity> 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<Quantity> 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<Quantity> 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<Quantity> 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:
|
||||
|
@ -26,6 +26,7 @@ import org.junit.jupiter.api.Test;
|
||||
/**
|
||||
* @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 class DeviceCollectionTest {
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
@ -209,7 +209,8 @@ public abstract class AbstractMieleThingHandlerTest extends JavaOSGiTest {
|
||||
}
|
||||
|
||||
protected AbstractMieleThingHandler createThingHandler(ThingTypeUID thingTypeUid, ThingUID thingUid,
|
||||
Class<? extends AbstractMieleThingHandler> expectedHandlerClass, String deviceIdentifier) {
|
||||
Class<? extends AbstractMieleThingHandler> expectedHandlerClass, String deviceIdentifier,
|
||||
String thingTypeVersion) {
|
||||
ThingRegistry registry = getThingRegistry();
|
||||
|
||||
List<Channel> channels = createChannelsForThingHandler(thingTypeUid, thingUid);
|
||||
@ -217,7 +218,8 @@ public abstract class AbstractMieleThingHandlerTest extends JavaOSGiTest {
|
||||
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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -28,22 +28,25 @@ import org.openhab.binding.mielecloud.internal.webservice.api.ActionsState;
|
||||
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 {
|
||||
@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
|
||||
@ -64,6 +67,8 @@ public class DishwasherDeviceThingHandlerTest extends AbstractMieleThingHandlerT
|
||||
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 class DishwasherDeviceThingHandlerTest extends AbstractMieleThingHandlerT
|
||||
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 class DishwasherDeviceThingHandlerTest extends AbstractMieleThingHandlerT
|
||||
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 class DishwasherDeviceThingHandlerTest extends AbstractMieleThingHandlerT
|
||||
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));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -28,22 +28,25 @@ import org.openhab.binding.mielecloud.internal.webservice.api.ActionsState;
|
||||
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 {
|
||||
@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
|
||||
@ -67,6 +70,7 @@ public class DryerDeviceThingHandlerTest extends AbstractMieleThingHandlerTest {
|
||||
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,7 @@ public class DryerDeviceThingHandlerTest extends AbstractMieleThingHandlerTest {
|
||||
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(ENERGY_CONSUMPTION_CURRENT));
|
||||
});
|
||||
}
|
||||
|
||||
@ -114,6 +119,7 @@ public class DryerDeviceThingHandlerTest extends AbstractMieleThingHandlerTest {
|
||||
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 +142,7 @@ public class DryerDeviceThingHandlerTest extends AbstractMieleThingHandlerTest {
|
||||
assertEquals(OnOffType.ON, getChannelState(INFO_STATE));
|
||||
assertEquals(OnOffType.OFF, getChannelState(LIGHT_SWITCH));
|
||||
assertEquals(OnOffType.OFF, getChannelState(DOOR_STATE));
|
||||
assertEquals(new QuantityType<>(2.5, Units.WATT_HOUR), getChannelState(ENERGY_CONSUMPTION_CURRENT));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -184,7 +184,7 @@ public class MieleHandlerFactoryTest extends JavaOSGiTest {
|
||||
}
|
||||
|
||||
private void testHandlerCanBeCreatedForMieleDevice(ThingTypeUID thingTypeUid, ThingUID thingUid, String label,
|
||||
Class<? extends ThingHandler> expectedHandlerClass)
|
||||
Class<? extends ThingHandler> expectedHandlerClass, String thingTypeVersion)
|
||||
throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
|
||||
// given:
|
||||
MieleWebservice webservice = mock(MieleWebservice.class);
|
||||
@ -196,7 +196,7 @@ public class MieleHandlerFactoryTest extends JavaOSGiTest {
|
||||
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 class MieleHandlerFactoryTest extends JavaOSGiTest {
|
||||
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");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -28,17 +28,19 @@ import org.openhab.binding.mielecloud.internal.webservice.api.ActionsState;
|
||||
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 {
|
||||
@ -46,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
|
||||
@ -71,6 +73,8 @@ public class WashingDeviceThingHandlerTest extends AbstractMieleThingHandlerTest
|
||||
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 class WashingDeviceThingHandlerTest extends AbstractMieleThingHandlerTest
|
||||
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 class WashingDeviceThingHandlerTest extends AbstractMieleThingHandlerTest
|
||||
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 class WashingDeviceThingHandlerTest extends AbstractMieleThingHandlerTest
|
||||
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));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user