[miele] Localization of state, program and phase (#11603)

* Initial changes for state, program and phase localization.
* Fix bridge configuration reload.
* Extracted DeviceMetaData from MieleBridgeHandler.
* Fix fallback to gateway text.
* Consolidate getMieleEnum in DeviceMetaData.
* Localize thing offline texts and increased accuracy.
* Validate language during bridge initialization.
* Interpret magic value for temperature.
* Add missing i18n channel label/description strings.
* Add missing washing machine phase texts in Dutch.
* Add missing French dishwasher phase texts.

Fixes #11602

Signed-off-by: Jacob Laursen <jacob-github@vindvejr.dk>
This commit is contained in:
jlaur
2021-11-29 08:16:08 +01:00
committed by GitHub
parent bea7197ede
commit 33e751c437
36 changed files with 1351 additions and 441 deletions

View File

@@ -128,15 +128,15 @@ Channels available for each appliance type are listed below.
| Program | Description | | Program | Description |
|---------|-------------------------------------| |---------|-------------------------------------|
| 26 | Pots & Pans | | 26 | Intensive |
| 27 | Clean Machine | | 27 | Maintenance programme |
| 28 | Economy | | 28 | ECO |
| 30 | Normal | | 30 | Normal |
| 32 | Sensor Wash | | 32 | Automatic |
| 34 | Energy Saver | | 34 | SolarSave |
| 35 | China & Crystal | | 35 | Gentle |
| 36 | Extra Quiet | | 36 | Extra Quiet |
| 37 | SaniWash | | 37 | Hygiene |
| 38 | QuickPowerWash | | 38 | QuickPowerWash |
| 42 | Tall items | | 42 | Tall items |
@@ -282,6 +282,7 @@ See oven.
| Program | Description | | Program | Description |
|---------|-------------------------------------| |---------|-------------------------------------|
| 10 | Automatic Plus | | 10 | Automatic Plus |
| 20 | Cottons |
| 23 | Cottons hygiene | | 23 | Cottons hygiene |
| 30 | Minimum iron | | 30 | Minimum iron |
| 31 | Gentle minimum iron | | 31 | Gentle minimum iron |
@@ -314,11 +315,11 @@ See oven.
| 513 | 1 | Programme running | | 513 | 1 | Programme running |
| 514 | 2 | Drying | | 514 | 2 | Drying |
| 515 | 3 | Drying Machine iron | | 515 | 3 | Drying Machine iron |
| 516 | 4 | Drying Hand iron (1) | | 516 | 4 | Drying Hand iron (2) |
| 517 | 5 | Drying Normal | | 517 | 5 | Drying Normal |
| 518 | 6 | Drying Normal+ | | 518 | 6 | Drying Normal+ |
| 519 | 7 | Cooling down | | 519 | 7 | Cooling down |
| 520 | 8 | Drying Hand iron (2) | | 520 | 8 | Drying Hand iron (1) |
| 522 | 10 | Finished | | 522 | 10 | Finished |
#### Washing Machine #### Washing Machine
@@ -338,7 +339,7 @@ See oven.
| finish | DateTime | Read | Time to finish the program running on the appliance | | finish | DateTime | Read | Time to finish the program running on the appliance |
| door | Contact | Read | Current state of the door of the appliance | | door | Contact | Read | Current state of the door of the appliance |
| switch | Switch | Write | Switch the appliance on or off | | switch | Switch | Write | Switch the appliance on or off |
| target | Number:Temperature | Read | Temperature of the selected program | | target | Number:Temperature | Read | Temperature of the selected program (10 °C = cold) |
| spinningspeed | String | Read | Spinning speed in the program running on the appliance | | spinningspeed | String | Read | Spinning speed in the program running on the appliance |
| powerConsumption | Number:Power | Read | Power consumption by the currently running program on the appliance | | powerConsumption | Number:Power | Read | Power consumption by the currently running program on the appliance |
| waterConsumption | Number:Volume | Read | Water consumption by the currently running program on the appliance | | waterConsumption | Number:Volume | Read | Water consumption by the currently running program on the appliance |

View File

@@ -0,0 +1,46 @@
/**
* Copyright (c) 2010-2021 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.miele.internal;
import java.util.Map.Entry;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
/**
* The {@link DeviceMetaData} class represents the Metadata node in the response JSON.
*
* @author Jacob Laursen - Initial contribution
*/
public class DeviceMetaData {
public String Filter;
public String description;
public String LocalizedID;
public String LocalizedValue;
public JsonObject MieleEnum;
public String access;
public String getMieleEnum(String s) {
if (this.MieleEnum == null) {
return null;
}
for (Entry<String, JsonElement> enumEntry : this.MieleEnum.entrySet()) {
if (enumEntry.getValue().getAsString().trim().equals(s.trim())) {
return enumEntry.getKey();
}
}
return null;
}
}

View File

@@ -12,9 +12,13 @@
*/ */
package org.openhab.binding.miele.internal; package org.openhab.binding.miele.internal;
import static org.openhab.binding.miele.internal.MieleBindingConstants.*;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Map;
import org.openhab.core.library.types.QuantityType; 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.SIUnits;
import org.openhab.core.types.State; import org.openhab.core.types.State;
import org.openhab.core.types.UnDefType; import org.openhab.core.types.UnDefType;
@@ -28,6 +32,15 @@ import org.openhab.core.types.UnDefType;
public class DeviceUtil { public class DeviceUtil {
private static final byte[] HEX_ARRAY = "0123456789ABCDEF".getBytes(StandardCharsets.US_ASCII); private static final byte[] HEX_ARRAY = "0123456789ABCDEF".getBytes(StandardCharsets.US_ASCII);
private static final String TEMPERATURE_UNDEFINED = "32768"; private static final String TEMPERATURE_UNDEFINED = "32768";
private static final String TEMPERATURE_COLD = "-32760";
private static final String TEXT_PREFIX = "miele.";
private static final Map<String, String> states = Map.ofEntries(Map.entry("1", "off"), Map.entry("2", "stand-by"),
Map.entry("3", "programmed"), Map.entry("4", "waiting-to-start"), Map.entry("5", "running"),
Map.entry("6", "paused"), Map.entry("7", "end"), Map.entry("8", "failure"), Map.entry("9", "abort"),
Map.entry("10", "idle"), Map.entry("11", "rinse-hold"), Map.entry("12", "service"),
Map.entry("13", "super-freezing"), Map.entry("14", "super-cooling"), Map.entry("15", "super-heating"),
Map.entry("144", "default"), Map.entry("145", "locked"), Map.entry("255", "not-connected"));
/** /**
* Convert byte array to hex representation. * Convert byte array to hex representation.
@@ -60,7 +73,59 @@ public class DeviceUtil {
if (TEMPERATURE_UNDEFINED.equals(s)) { if (TEMPERATURE_UNDEFINED.equals(s)) {
return UnDefType.UNDEF; return UnDefType.UNDEF;
} }
if (TEMPERATURE_COLD.equals(s)) {
return new QuantityType<>(10, SIUnits.CELSIUS);
}
int temperature = Integer.parseInt(s); int temperature = Integer.parseInt(s);
return new QuantityType<>(temperature, SIUnits.CELSIUS); return new QuantityType<>(temperature, SIUnits.CELSIUS);
} }
/**
* Get state text for provided string taking into consideration {@link DeviceMetaData}
* as well as built-in/translated strings.
*/
public static State getStateTextState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
return getTextState(s, dmd, translationProvider, states, MISSING_STATE_TEXT_PREFIX, "");
}
/**
* Get text for provided string taking into consideration {@link DeviceMetaData}
* as well as built-in/translated strings.
*
* @param s Raw string to be processed
* @param dmd {@link DeviceMetaData} possibly containing LocalizedValue and/or enum from gateway
* @param translationProvider {@link MieleTranslationProvider} for localization support
* @param valueMap Map of numeric values with corresponding text keys
* @param propertyPrefix Property prefix appended to text key (including dot)
* @param appliancePrefix Appliance prefix appended to text key (including dot)
* @return Text string as State
*/
public static State getTextState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider,
Map<String, String> valueMap, String propertyPrefix, String appliancePrefix) {
if ("0".equals(s)) {
return UnDefType.UNDEF;
}
String gatewayText = null;
if (dmd != null) {
if (dmd.LocalizedValue != null && !dmd.LocalizedValue.isEmpty()) {
gatewayText = dmd.LocalizedValue;
} else {
gatewayText = dmd.getMieleEnum(s);
}
}
String value = valueMap.get(s);
if (value != null) {
String key = TEXT_PREFIX + propertyPrefix + appliancePrefix + value;
return new StringType(
translationProvider.getText(key, gatewayText != null ? gatewayText : propertyPrefix + s));
}
if (gatewayText != null) {
return new StringType(gatewayText);
}
return new StringType(propertyPrefix + s);
}
} }

View File

@@ -97,12 +97,21 @@ public class MieleBindingConstants {
public static final int STATE_NOT_CONNECTED = 255; public static final int STATE_NOT_CONNECTED = 255;
// Miele missing string prefixes // Miele missing string prefixes
public static final String MISSING_STATE_TEXT_PREFIX = "state.";
public static final String MISSING_PROGRAM_TEXT_PREFIX = "program."; public static final String MISSING_PROGRAM_TEXT_PREFIX = "program.";
public static final String MISSING_PHASE_TEXT_PREFIX = "phase."; public static final String MISSING_PHASE_TEXT_PREFIX = "phase.";
// Miele appliance localization text prefixes
public static final String MIELE_COFFEE_MACHINE_TEXT_PREFIX = "coffeemachine.";
public static final String MIELE_DISHWASHER_TEXT_PREFIX = "dishwasher.";
public static final String MIELE_OVEN_TEXT_PREFIX = "oven.";
public static final String MIELE_TUMBLE_DRYER_TEXT_PREFIX = "tumbledryer.";
public static final String MIELE_WASHING_MACHINE_TEXT_PREFIX = "washingmachine.";
// Bridge config properties // Bridge config properties
public static final String HOST = "ipAddress"; public static final String HOST = "ipAddress";
public static final String INTERFACE = "interface"; public static final String INTERFACE = "interface";
public static final String USER_NAME = "userName"; public static final String USER_NAME = "userName";
public static final String PASSWORD = "password"; public static final String PASSWORD = "password";
public static final String LANGUAGE = "language";
} }

View File

@@ -35,6 +35,8 @@ import org.openhab.binding.miele.internal.handler.TumbleDryerHandler;
import org.openhab.binding.miele.internal.handler.WashingMachineHandler; import org.openhab.binding.miele.internal.handler.WashingMachineHandler;
import org.openhab.core.config.core.Configuration; import org.openhab.core.config.core.Configuration;
import org.openhab.core.config.discovery.DiscoveryService; import org.openhab.core.config.discovery.DiscoveryService;
import org.openhab.core.i18n.LocaleProvider;
import org.openhab.core.i18n.TranslationProvider;
import org.openhab.core.thing.Bridge; import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.Thing; import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingTypeUID; import org.openhab.core.thing.ThingTypeUID;
@@ -43,7 +45,10 @@ import org.openhab.core.thing.binding.BaseThingHandlerFactory;
import org.openhab.core.thing.binding.ThingHandler; import org.openhab.core.thing.binding.ThingHandler;
import org.openhab.core.thing.binding.ThingHandlerFactory; import org.openhab.core.thing.binding.ThingHandlerFactory;
import org.osgi.framework.ServiceRegistration; import org.osgi.framework.ServiceRegistration;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
/** /**
* The {@link MieleHandlerFactory} is responsible for creating things and thing * The {@link MieleHandlerFactory} is responsible for creating things and thing
@@ -59,8 +64,18 @@ public class MieleHandlerFactory extends BaseThingHandlerFactory {
MieleApplianceHandler.SUPPORTED_THING_TYPES.stream()) MieleApplianceHandler.SUPPORTED_THING_TYPES.stream())
.collect(Collectors.toSet()); .collect(Collectors.toSet());
private final TranslationProvider i18nProvider;
private final LocaleProvider localeProvider;
private Map<ThingUID, ServiceRegistration<?>> discoveryServiceRegs = new HashMap<>(); private Map<ThingUID, ServiceRegistration<?>> discoveryServiceRegs = new HashMap<>();
@Activate
public MieleHandlerFactory(final @Reference TranslationProvider i18nProvider,
final @Reference LocaleProvider localeProvider, ComponentContext componentContext) {
this.i18nProvider = i18nProvider;
this.localeProvider = localeProvider;
}
@Override @Override
public boolean supportsThingType(ThingTypeUID thingTypeUID) { public boolean supportsThingType(ThingTypeUID thingTypeUID) {
return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID); return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
@@ -89,31 +104,31 @@ public class MieleHandlerFactory extends BaseThingHandlerFactory {
return handler; return handler;
} else if (MieleApplianceHandler.SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())) { } else if (MieleApplianceHandler.SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())) {
if (thing.getThingTypeUID().equals(THING_TYPE_HOOD)) { if (thing.getThingTypeUID().equals(THING_TYPE_HOOD)) {
return new HoodHandler(thing); return new HoodHandler(thing, i18nProvider, localeProvider);
} }
if (thing.getThingTypeUID().equals(THING_TYPE_FRIDGEFREEZER)) { if (thing.getThingTypeUID().equals(THING_TYPE_FRIDGEFREEZER)) {
return new FridgeFreezerHandler(thing); return new FridgeFreezerHandler(thing, i18nProvider, localeProvider);
} }
if (thing.getThingTypeUID().equals(THING_TYPE_FRIDGE)) { if (thing.getThingTypeUID().equals(THING_TYPE_FRIDGE)) {
return new FridgeHandler(thing); return new FridgeHandler(thing, i18nProvider, localeProvider);
} }
if (thing.getThingTypeUID().equals(THING_TYPE_OVEN)) { if (thing.getThingTypeUID().equals(THING_TYPE_OVEN)) {
return new OvenHandler(thing); return new OvenHandler(thing, i18nProvider, localeProvider);
} }
if (thing.getThingTypeUID().equals(THING_TYPE_HOB)) { if (thing.getThingTypeUID().equals(THING_TYPE_HOB)) {
return new HobHandler(thing); return new HobHandler(thing, i18nProvider, localeProvider);
} }
if (thing.getThingTypeUID().equals(THING_TYPE_WASHINGMACHINE)) { if (thing.getThingTypeUID().equals(THING_TYPE_WASHINGMACHINE)) {
return new WashingMachineHandler(thing); return new WashingMachineHandler(thing, i18nProvider, localeProvider);
} }
if (thing.getThingTypeUID().equals(THING_TYPE_DRYER)) { if (thing.getThingTypeUID().equals(THING_TYPE_DRYER)) {
return new TumbleDryerHandler(thing); return new TumbleDryerHandler(thing, i18nProvider, localeProvider);
} }
if (thing.getThingTypeUID().equals(THING_TYPE_DISHWASHER)) { if (thing.getThingTypeUID().equals(THING_TYPE_DISHWASHER)) {
return new DishWasherHandler(thing); return new DishWasherHandler(thing, i18nProvider, localeProvider);
} }
if (thing.getThingTypeUID().equals(THING_TYPE_COFFEEMACHINE)) { if (thing.getThingTypeUID().equals(THING_TYPE_COFFEEMACHINE)) {
return new CoffeeMachineHandler(thing); return new CoffeeMachineHandler(thing, i18nProvider, localeProvider);
} }
} }

View File

@@ -0,0 +1,60 @@
/**
* Copyright (c) 2010-2021 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.miele.internal;
import java.util.Locale;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.i18n.LocaleProvider;
import org.openhab.core.i18n.TranslationProvider;
import org.osgi.framework.Bundle;
import org.osgi.framework.FrameworkUtil;
/**
* {@link MieleTranslationProvider} provides i18n message lookup
*
* @author Jacob Laursen - Initial contribution
*/
@NonNullByDefault
public class MieleTranslationProvider {
private final Bundle bundle;
private final TranslationProvider i18nProvider;
private final LocaleProvider localeProvider;
@Nullable
private final Locale locale;
public MieleTranslationProvider(TranslationProvider i18nProvider, LocaleProvider localeProvider) {
this.bundle = FrameworkUtil.getBundle(this.getClass());
this.i18nProvider = i18nProvider;
this.localeProvider = localeProvider;
this.locale = null;
}
public MieleTranslationProvider(TranslationProvider i18nProvider, LocaleProvider localeProvider, Locale locale) {
this.bundle = FrameworkUtil.getBundle(this.getClass());
this.i18nProvider = i18nProvider;
this.localeProvider = localeProvider;
this.locale = locale;
}
public String getText(String key, String defaultText, @Nullable Object... arguments) {
String text = i18nProvider.getText(bundle, key, defaultText,
locale != null ? locale : localeProvider.getLocale(), arguments);
if (text == null) {
return defaultText;
}
return text;
}
}

View File

@@ -12,7 +12,8 @@
*/ */
package org.openhab.binding.miele.internal.handler; package org.openhab.binding.miele.internal.handler;
import org.openhab.binding.miele.internal.handler.MieleBridgeHandler.DeviceMetaData; import org.openhab.binding.miele.internal.DeviceMetaData;
import org.openhab.binding.miele.internal.MieleTranslationProvider;
import org.openhab.core.types.State; import org.openhab.core.types.State;
/** /**
@@ -51,6 +52,17 @@ public interface ApplianceChannelSelector {
*/ */
boolean isExtendedState(); boolean isExtendedState();
/**
* Returns a State for the given string, taking into
* account the metadata provided as well as text
* translations for corresponding numeric values.
*
* @param s - the value to be used to instantiate the State
* @param dmd - the device meta data
* @param translationProvider {@link MieleTranslationProvider} instance
*/
State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider);
/** /**
* Returns a State for the given string, taking into * Returns a State for the given string, taking into
* account the metadata provided. The meta data is sent by * account the metadata provided. The meta data is sent by

View File

@@ -17,9 +17,10 @@ import static org.openhab.binding.miele.internal.MieleBindingConstants.*;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Collections; import java.util.Collections;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import org.openhab.binding.miele.internal.handler.MieleBridgeHandler.DeviceMetaData; import org.openhab.binding.miele.internal.DeviceMetaData;
import org.openhab.binding.miele.internal.DeviceUtil;
import org.openhab.binding.miele.internal.MieleTranslationProvider;
import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.OpenClosedType; import org.openhab.core.library.types.OpenClosedType;
@@ -30,8 +31,6 @@ import org.openhab.core.types.UnDefType;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.google.gson.JsonElement;
/** /**
* The {@link ApplianceChannelSelector} for coffee machines * The {@link ApplianceChannelSelector} for coffee machines
* *
@@ -42,35 +41,46 @@ public enum CoffeeMachineChannelSelector implements ApplianceChannelSelector {
PRODUCT_TYPE("productTypeId", "productType", StringType.class, true), PRODUCT_TYPE("productTypeId", "productType", StringType.class, true),
DEVICE_TYPE("mieleDeviceType", "deviceType", StringType.class, true), DEVICE_TYPE("mieleDeviceType", "deviceType", StringType.class, true),
STATE_TEXT(STATE_PROPERTY_NAME, STATE_TEXT_CHANNEL_ID, StringType.class, false), STATE_TEXT(STATE_PROPERTY_NAME, STATE_TEXT_CHANNEL_ID, StringType.class, false) {
STATE(null, STATE_CHANNEL_ID, DecimalType.class, false),
PROGRAM_TEXT(PROGRAM_ID_PROPERTY_NAME, PROGRAM_TEXT_CHANNEL_ID, StringType.class, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
State state = getTextState(s, dmd, programs, MISSING_PROGRAM_TEXT_PREFIX); State state = DeviceUtil.getStateTextState(s, dmd, translationProvider);
if (state != null) { if (state != null) {
return state; return state;
} }
return super.getState(s, dmd); return super.getState(s, dmd, translationProvider);
}
},
STATE(null, STATE_CHANNEL_ID, DecimalType.class, false),
PROGRAM_TEXT(PROGRAM_ID_PROPERTY_NAME, PROGRAM_TEXT_CHANNEL_ID, StringType.class, false) {
@Override
public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
State state = DeviceUtil.getTextState(s, dmd, translationProvider, programs, MISSING_PROGRAM_TEXT_PREFIX,
MIELE_COFFEE_MACHINE_TEXT_PREFIX);
if (state != null) {
return state;
}
return super.getState(s, dmd, translationProvider);
} }
}, },
PROGRAM(null, PROGRAM_CHANNEL_ID, DecimalType.class, false), PROGRAM(null, PROGRAM_CHANNEL_ID, DecimalType.class, false),
PROGRAMTYPE("programType", "type", StringType.class, false), PROGRAMTYPE("programType", "type", StringType.class, false),
PROGRAM_PHASE_TEXT(PHASE_PROPERTY_NAME, PHASE_TEXT_CHANNEL_ID, StringType.class, false) { PROGRAM_PHASE_TEXT(PHASE_PROPERTY_NAME, PHASE_TEXT_CHANNEL_ID, StringType.class, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
State state = getTextState(s, dmd, phases, MISSING_PHASE_TEXT_PREFIX); State state = DeviceUtil.getTextState(s, dmd, translationProvider, phases, MISSING_PHASE_TEXT_PREFIX,
MIELE_COFFEE_MACHINE_TEXT_PREFIX);
if (state != null) { if (state != null) {
return state; return state;
} }
return super.getState(s, dmd); return super.getState(s, dmd, translationProvider);
} }
}, },
PROGRAM_PHASE(RAW_PHASE_PROPERTY_NAME, PHASE_CHANNEL_ID, DecimalType.class, false), PROGRAM_PHASE(RAW_PHASE_PROPERTY_NAME, PHASE_CHANNEL_ID, DecimalType.class, false),
// lightingStatus signalFailure signalInfo // lightingStatus signalFailure signalInfo
DOOR("signalDoor", "door", OpenClosedType.class, false) { DOOR("signalDoor", "door", OpenClosedType.class, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
if ("true".equals(s)) { if ("true".equals(s)) {
return getState("OPEN"); return getState("OPEN");
} }
@@ -128,10 +138,15 @@ public enum CoffeeMachineChannelSelector implements ApplianceChannelSelector {
return false; return false;
} }
@Override
public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
return this.getState(s, dmd);
}
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd) {
if (dmd != null) { if (dmd != null) {
String localizedValue = getMieleEnum(s, dmd); String localizedValue = dmd.getMieleEnum(s);
if (localizedValue == null) { if (localizedValue == null) {
localizedValue = dmd.LocalizedValue; localizedValue = dmd.LocalizedValue;
} }
@@ -158,34 +173,4 @@ public enum CoffeeMachineChannelSelector implements ApplianceChannelSelector {
return null; return null;
} }
public State getTextState(String s, DeviceMetaData dmd, Map<String, String> valueMap, String prefix) {
if ("0".equals(s)) {
return UnDefType.UNDEF;
}
if (dmd == null || dmd.LocalizedValue == null || dmd.LocalizedValue.startsWith(prefix)) {
String text = valueMap.get(s);
if (text != null) {
return getState(text);
}
if (dmd == null || dmd.LocalizedValue == null) {
return getState(prefix + s);
}
}
return null;
}
public String getMieleEnum(String s, DeviceMetaData dmd) {
if (dmd.MieleEnum != null) {
for (Entry<String, JsonElement> enumEntry : dmd.MieleEnum.entrySet()) {
if (enumEntry.getValue().getAsString().trim().equals(s.trim())) {
return enumEntry.getKey();
}
}
}
return null;
}
} }

View File

@@ -15,6 +15,8 @@ package org.openhab.binding.miele.internal.handler;
import static org.openhab.binding.miele.internal.MieleBindingConstants.APPLIANCE_ID; import static org.openhab.binding.miele.internal.MieleBindingConstants.APPLIANCE_ID;
import static org.openhab.binding.miele.internal.MieleBindingConstants.MIELE_DEVICE_CLASS_COFFEE_SYSTEM; import static org.openhab.binding.miele.internal.MieleBindingConstants.MIELE_DEVICE_CLASS_COFFEE_SYSTEM;
import org.openhab.core.i18n.LocaleProvider;
import org.openhab.core.i18n.TranslationProvider;
import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.OnOffType;
import org.openhab.core.thing.ChannelUID; import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing; import org.openhab.core.thing.Thing;
@@ -37,8 +39,9 @@ public class CoffeeMachineHandler extends MieleApplianceHandler<CoffeeMachineCha
private final Logger logger = LoggerFactory.getLogger(CoffeeMachineHandler.class); private final Logger logger = LoggerFactory.getLogger(CoffeeMachineHandler.class);
public CoffeeMachineHandler(Thing thing) { public CoffeeMachineHandler(Thing thing, TranslationProvider i18nProvider, LocaleProvider localeProvider) {
super(thing, CoffeeMachineChannelSelector.class, MIELE_DEVICE_CLASS_COFFEE_SYSTEM); super(thing, i18nProvider, localeProvider, CoffeeMachineChannelSelector.class,
MIELE_DEVICE_CLASS_COFFEE_SYSTEM);
} }
@Override @Override

View File

@@ -19,6 +19,8 @@ import static org.openhab.binding.miele.internal.MieleBindingConstants.WATER_CON
import java.math.BigDecimal; import java.math.BigDecimal;
import org.openhab.core.i18n.LocaleProvider;
import org.openhab.core.i18n.TranslationProvider;
import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.QuantityType; import org.openhab.core.library.types.QuantityType;
import org.openhab.core.library.unit.Units; import org.openhab.core.library.unit.Units;
@@ -49,8 +51,8 @@ public class DishWasherHandler extends MieleApplianceHandler<DishwasherChannelSe
private final Logger logger = LoggerFactory.getLogger(DishWasherHandler.class); private final Logger logger = LoggerFactory.getLogger(DishWasherHandler.class);
public DishWasherHandler(Thing thing) { public DishWasherHandler(Thing thing, TranslationProvider i18nProvider, LocaleProvider localeProvider) {
super(thing, DishwasherChannelSelector.class, MIELE_DEVICE_CLASS_DISHWASHER); super(thing, i18nProvider, localeProvider, DishwasherChannelSelector.class, MIELE_DEVICE_CLASS_DISHWASHER);
} }
@Override @Override

View File

@@ -19,10 +19,11 @@ import java.lang.reflect.Method;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.TimeZone; import java.util.TimeZone;
import org.openhab.binding.miele.internal.handler.MieleBridgeHandler.DeviceMetaData; import org.openhab.binding.miele.internal.DeviceMetaData;
import org.openhab.binding.miele.internal.DeviceUtil;
import org.openhab.binding.miele.internal.MieleTranslationProvider;
import org.openhab.core.library.types.DateTimeType; import org.openhab.core.library.types.DateTimeType;
import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.OnOffType;
@@ -35,8 +36,6 @@ import org.openhab.core.types.UnDefType;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.google.gson.JsonElement;
/** /**
* The {@link ApplianceChannelSelector} for dishwashers * The {@link ApplianceChannelSelector} for dishwashers
* *
@@ -48,33 +47,44 @@ public enum DishwasherChannelSelector implements ApplianceChannelSelector {
PRODUCT_TYPE("productTypeId", "productType", StringType.class, true, false), PRODUCT_TYPE("productTypeId", "productType", StringType.class, true, false),
DEVICE_TYPE("mieleDeviceType", "deviceType", StringType.class, true, false), DEVICE_TYPE("mieleDeviceType", "deviceType", StringType.class, true, false),
STATE_TEXT(STATE_PROPERTY_NAME, STATE_TEXT_CHANNEL_ID, StringType.class, false, false), STATE_TEXT(STATE_PROPERTY_NAME, STATE_TEXT_CHANNEL_ID, StringType.class, false, false) {
STATE(null, STATE_CHANNEL_ID, DecimalType.class, false, false),
PROGRAM_TEXT(PROGRAM_ID_PROPERTY_NAME, PROGRAM_TEXT_CHANNEL_ID, StringType.class, false, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
State state = getTextState(s, dmd, programs, MISSING_PROGRAM_TEXT_PREFIX); State state = DeviceUtil.getStateTextState(s, dmd, translationProvider);
if (state != null) { if (state != null) {
return state; return state;
} }
return super.getState(s, dmd); return super.getState(s, dmd, translationProvider);
}
},
STATE(null, STATE_CHANNEL_ID, DecimalType.class, false, false),
PROGRAM_TEXT(PROGRAM_ID_PROPERTY_NAME, PROGRAM_TEXT_CHANNEL_ID, StringType.class, false, false) {
@Override
public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
State state = DeviceUtil.getTextState(s, dmd, translationProvider, programs, MISSING_PROGRAM_TEXT_PREFIX,
MIELE_DISHWASHER_TEXT_PREFIX);
if (state != null) {
return state;
}
return super.getState(s, dmd, translationProvider);
} }
}, },
PROGRAM(null, PROGRAM_CHANNEL_ID, DecimalType.class, false, false), PROGRAM(null, PROGRAM_CHANNEL_ID, DecimalType.class, false, false),
PROGRAM_PHASE_TEXT(PHASE_PROPERTY_NAME, PHASE_TEXT_CHANNEL_ID, StringType.class, false, false) { PROGRAM_PHASE_TEXT(PHASE_PROPERTY_NAME, PHASE_TEXT_CHANNEL_ID, StringType.class, false, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
State state = getTextState(s, dmd, phases, MISSING_PHASE_TEXT_PREFIX); State state = DeviceUtil.getTextState(s, dmd, translationProvider, phases, MISSING_PHASE_TEXT_PREFIX,
MIELE_DISHWASHER_TEXT_PREFIX);
if (state != null) { if (state != null) {
return state; return state;
} }
return super.getState(s, dmd); return super.getState(s, dmd, translationProvider);
} }
}, },
PROGRAM_PHASE(RAW_PHASE_PROPERTY_NAME, PHASE_CHANNEL_ID, DecimalType.class, false, false), PROGRAM_PHASE(RAW_PHASE_PROPERTY_NAME, PHASE_CHANNEL_ID, DecimalType.class, false, false),
START_TIME("startTime", "start", DateTimeType.class, false, false) { START_TIME("startTime", "start", DateTimeType.class, false, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
Date date = new Date(); Date date = new Date();
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT+0")); dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT+0"));
@@ -88,7 +98,7 @@ public enum DishwasherChannelSelector implements ApplianceChannelSelector {
}, },
DURATION("duration", "duration", DateTimeType.class, false, false) { DURATION("duration", "duration", DateTimeType.class, false, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
Date date = new Date(); Date date = new Date();
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT+0")); dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT+0"));
@@ -102,7 +112,7 @@ public enum DishwasherChannelSelector implements ApplianceChannelSelector {
}, },
ELAPSED_TIME("elapsedTime", "elapsed", DateTimeType.class, false, false) { ELAPSED_TIME("elapsedTime", "elapsed", DateTimeType.class, false, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
Date date = new Date(); Date date = new Date();
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT+0")); dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT+0"));
@@ -116,7 +126,7 @@ public enum DishwasherChannelSelector implements ApplianceChannelSelector {
}, },
FINISH_TIME("finishTime", "finish", DateTimeType.class, false, false) { FINISH_TIME("finishTime", "finish", DateTimeType.class, false, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
Date date = new Date(); Date date = new Date();
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT+0")); dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT+0"));
@@ -130,7 +140,7 @@ public enum DishwasherChannelSelector implements ApplianceChannelSelector {
}, },
DOOR("signalDoor", "door", OpenClosedType.class, false, false) { DOOR("signalDoor", "door", OpenClosedType.class, false, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
if ("true".equals(s)) { if ("true".equals(s)) {
return getState("OPEN"); return getState("OPEN");
} }
@@ -150,13 +160,13 @@ public enum DishwasherChannelSelector implements ApplianceChannelSelector {
private final Logger logger = LoggerFactory.getLogger(DishwasherChannelSelector.class); private final Logger logger = LoggerFactory.getLogger(DishwasherChannelSelector.class);
private static final Map<String, String> programs = Map.ofEntries(entry("26", "Pots & Pans"), private static final Map<String, String> programs = Map.ofEntries(entry("26", "intensive"),
entry("27", "Clean Machine"), entry("28", "Economy"), entry("30", "Normal"), entry("32", "Sensor Wash"), entry("27", "maintenance-programme"), entry("28", "eco"), entry("30", "normal"), entry("32", "automatic"),
entry("34", "Energy Saver"), entry("35", "China & Crystal"), entry("36", "Extra Quiet"), entry("34", "solarsave"), entry("35", "gentle"), entry("36", "extra-quiet"), entry("37", "hygiene"),
entry("37", "SaniWash"), entry("38", "QuickPowerWash"), entry("42", "Tall items")); entry("38", "quickpowerwash"), entry("42", "tall-items"));
private static final Map<String, String> phases = Map.ofEntries(entry("2", "Pre-Wash"), entry("3", "Main Wash"), private static final Map<String, String> phases = Map.ofEntries(entry("2", "pre-wash"), entry("3", "main-wash"),
entry("4", "Rinses"), entry("6", "Final rinse"), entry("7", "Drying"), entry("8", "Finished")); entry("4", "rinses"), entry("6", "final-rinse"), entry("7", "drying"), entry("8", "finished"));
private final String mieleID; private final String mieleID;
private final String channelID; private final String channelID;
@@ -198,10 +208,15 @@ public enum DishwasherChannelSelector implements ApplianceChannelSelector {
return isExtendedState; return isExtendedState;
} }
@Override
public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
return this.getState(s, dmd);
}
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd) {
if (dmd != null) { if (dmd != null) {
String localizedValue = getMieleEnum(s, dmd); String localizedValue = dmd.getMieleEnum(s);
if (localizedValue == null) { if (localizedValue == null) {
localizedValue = dmd.LocalizedValue; localizedValue = dmd.LocalizedValue;
} }
@@ -228,34 +243,4 @@ public enum DishwasherChannelSelector implements ApplianceChannelSelector {
return null; return null;
} }
public State getTextState(String s, DeviceMetaData dmd, Map<String, String> valueMap, String prefix) {
if ("0".equals(s)) {
return UnDefType.UNDEF;
}
if (dmd == null || dmd.LocalizedValue == null || dmd.LocalizedValue.startsWith(prefix)) {
String text = valueMap.get(s);
if (text != null) {
return getState(text);
}
if (dmd == null || dmd.LocalizedValue == null) {
return getState(prefix + s);
}
}
return null;
}
public String getMieleEnum(String s, DeviceMetaData dmd) {
if (dmd.MieleEnum != null) {
for (Entry<String, JsonElement> enumEntry : dmd.MieleEnum.entrySet()) {
if (enumEntry.getValue().getAsString().trim().equals(s.trim())) {
return enumEntry.getKey();
}
}
}
return null;
}
} }

View File

@@ -16,7 +16,7 @@ package org.openhab.binding.miele.internal.handler;
* Appliance handlers can implement the {@link ExtendedDeviceStateListener} interface * Appliance handlers can implement the {@link ExtendedDeviceStateListener} interface
* to extract additional information from the ExtendedDeviceState property. * to extract additional information from the ExtendedDeviceState property.
* *
* @author Jacob Laursen - Added power/water consumption channels * @author Jacob Laursen - Initial contribution
*/ */
public interface ExtendedDeviceStateListener { public interface ExtendedDeviceStateListener {
void onApplianceExtendedStateChanged(byte[] extendedDeviceState); void onApplianceExtendedStateChanged(byte[] extendedDeviceState);

View File

@@ -15,10 +15,10 @@ package org.openhab.binding.miele.internal.handler;
import static org.openhab.binding.miele.internal.MieleBindingConstants.*; import static org.openhab.binding.miele.internal.MieleBindingConstants.*;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Map.Entry;
import org.openhab.binding.miele.internal.DeviceMetaData;
import org.openhab.binding.miele.internal.DeviceUtil; import org.openhab.binding.miele.internal.DeviceUtil;
import org.openhab.binding.miele.internal.handler.MieleBridgeHandler.DeviceMetaData; import org.openhab.binding.miele.internal.MieleTranslationProvider;
import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.OpenClosedType; import org.openhab.core.library.types.OpenClosedType;
@@ -30,8 +30,6 @@ import org.openhab.core.types.UnDefType;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.google.gson.JsonElement;
/** /**
* The {@link ApplianceChannelSelector} for fridges * The {@link ApplianceChannelSelector} for fridges
* *
@@ -42,25 +40,34 @@ public enum FridgeChannelSelector implements ApplianceChannelSelector {
PRODUCT_TYPE("productTypeId", "productType", StringType.class, true), PRODUCT_TYPE("productTypeId", "productType", StringType.class, true),
DEVICE_TYPE("mieleDeviceType", "deviceType", StringType.class, true), DEVICE_TYPE("mieleDeviceType", "deviceType", StringType.class, true),
STATE_TEXT(STATE_PROPERTY_NAME, STATE_TEXT_CHANNEL_ID, StringType.class, false), STATE_TEXT(STATE_PROPERTY_NAME, STATE_TEXT_CHANNEL_ID, StringType.class, false) {
@Override
public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
State state = DeviceUtil.getStateTextState(s, dmd, translationProvider);
if (state != null) {
return state;
}
return super.getState(s, dmd, translationProvider);
}
},
STATE(null, STATE_CHANNEL_ID, DecimalType.class, false), STATE(null, STATE_CHANNEL_ID, DecimalType.class, false),
SUPERCOOL(null, SUPERCOOL_CHANNEL_ID, OnOffType.class, false), SUPERCOOL(null, SUPERCOOL_CHANNEL_ID, OnOffType.class, false),
FRIDGECURRENTTEMP("currentTemperature", "current", QuantityType.class, false) { FRIDGECURRENTTEMP("currentTemperature", "current", QuantityType.class, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
return getTemperatureState(s); return getTemperatureState(s);
} }
}, },
FRIDGETARGETTEMP("targetTemperature", "target", QuantityType.class, false) { FRIDGETARGETTEMP("targetTemperature", "target", QuantityType.class, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
return getTemperatureState(s); return getTemperatureState(s);
} }
}, },
DOOR("signalDoor", "door", OpenClosedType.class, false) { DOOR("signalDoor", "door", OpenClosedType.class, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
if ("true".equals(s)) { if ("true".equals(s)) {
return getState("OPEN"); return getState("OPEN");
} }
@@ -113,10 +120,15 @@ public enum FridgeChannelSelector implements ApplianceChannelSelector {
return false; return false;
} }
@Override
public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
return this.getState(s, dmd);
}
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd) {
if (dmd != null) { if (dmd != null) {
String localizedValue = getMieleEnum(s, dmd); String localizedValue = dmd.getMieleEnum(s);
if (localizedValue == null) { if (localizedValue == null) {
localizedValue = dmd.LocalizedValue; localizedValue = dmd.LocalizedValue;
} }
@@ -152,16 +164,4 @@ public enum FridgeChannelSelector implements ApplianceChannelSelector {
return UnDefType.UNDEF; return UnDefType.UNDEF;
} }
} }
public String getMieleEnum(String s, DeviceMetaData dmd) {
if (dmd.MieleEnum != null) {
for (Entry<String, JsonElement> enumEntry : dmd.MieleEnum.entrySet()) {
if (enumEntry.getValue().getAsString().trim().equals(s.trim())) {
return enumEntry.getKey();
}
}
}
return null;
}
} }

View File

@@ -15,10 +15,10 @@ package org.openhab.binding.miele.internal.handler;
import static org.openhab.binding.miele.internal.MieleBindingConstants.*; import static org.openhab.binding.miele.internal.MieleBindingConstants.*;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Map.Entry;
import org.openhab.binding.miele.internal.DeviceMetaData;
import org.openhab.binding.miele.internal.DeviceUtil; import org.openhab.binding.miele.internal.DeviceUtil;
import org.openhab.binding.miele.internal.handler.MieleBridgeHandler.DeviceMetaData; import org.openhab.binding.miele.internal.MieleTranslationProvider;
import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.OpenClosedType; import org.openhab.core.library.types.OpenClosedType;
@@ -30,8 +30,6 @@ import org.openhab.core.types.UnDefType;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.google.gson.JsonElement;
/** /**
* The {@link ApplianceChannelSelector} for fridges with * The {@link ApplianceChannelSelector} for fridges with
* a freezer compartment * a freezer compartment
@@ -43,7 +41,16 @@ public enum FridgeFreezerChannelSelector implements ApplianceChannelSelector {
PRODUCT_TYPE("productTypeId", "productType", StringType.class, true), PRODUCT_TYPE("productTypeId", "productType", StringType.class, true),
DEVICE_TYPE("mieleDeviceType", "deviceType", StringType.class, true), DEVICE_TYPE("mieleDeviceType", "deviceType", StringType.class, true),
STATE_TEXT(STATE_PROPERTY_NAME, STATE_TEXT_CHANNEL_ID, StringType.class, false), STATE_TEXT(STATE_PROPERTY_NAME, STATE_TEXT_CHANNEL_ID, StringType.class, false) {
@Override
public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
State state = DeviceUtil.getStateTextState(s, dmd, translationProvider);
if (state != null) {
return state;
}
return super.getState(s, dmd, translationProvider);
}
},
STATE(null, STATE_CHANNEL_ID, DecimalType.class, false), STATE(null, STATE_CHANNEL_ID, DecimalType.class, false),
FREEZERSTATE("freezerState", "freezerstate", StringType.class, false), FREEZERSTATE("freezerState", "freezerstate", StringType.class, false),
FRIDGESTATE("fridgeState", "fridgestate", StringType.class, false), FRIDGESTATE("fridgeState", "fridgestate", StringType.class, false),
@@ -51,32 +58,32 @@ public enum FridgeFreezerChannelSelector implements ApplianceChannelSelector {
SUPERFREEZE(null, SUPERFREEZE_CHANNEL_ID, OnOffType.class, false), SUPERFREEZE(null, SUPERFREEZE_CHANNEL_ID, OnOffType.class, false),
FREEZERCURRENTTEMP("freezerCurrentTemperature", "freezercurrent", QuantityType.class, false) { FREEZERCURRENTTEMP("freezerCurrentTemperature", "freezercurrent", QuantityType.class, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
return getTemperatureState(s); return getTemperatureState(s);
} }
}, },
FREEZERTARGETTEMP("freezerTargetTemperature", "freezertarget", QuantityType.class, false) { FREEZERTARGETTEMP("freezerTargetTemperature", "freezertarget", QuantityType.class, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
return getTemperatureState(s); return getTemperatureState(s);
} }
}, },
FRIDGECURRENTTEMP("fridgeCurrentTemperature", "fridgecurrent", QuantityType.class, false) { FRIDGECURRENTTEMP("fridgeCurrentTemperature", "fridgecurrent", QuantityType.class, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
return getTemperatureState(s); return getTemperatureState(s);
} }
}, },
FRIDGETARGETTEMP("fridgeTargetTemperature", "fridgetarget", QuantityType.class, false) { FRIDGETARGETTEMP("fridgeTargetTemperature", "fridgetarget", QuantityType.class, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
return getTemperatureState(s); return getTemperatureState(s);
} }
}, },
DOOR("signalDoor", "door", OpenClosedType.class, false) { DOOR("signalDoor", "door", OpenClosedType.class, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
if ("true".equals(s)) { if ("true".equals(s)) {
return getState("OPEN"); return getState("OPEN");
} }
@@ -130,10 +137,15 @@ public enum FridgeFreezerChannelSelector implements ApplianceChannelSelector {
return false; return false;
} }
@Override
public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
return this.getState(s, dmd);
}
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd) {
if (dmd != null) { if (dmd != null) {
String localizedValue = getMieleEnum(s, dmd); String localizedValue = dmd.getMieleEnum(s);
if (localizedValue == null) { if (localizedValue == null) {
localizedValue = dmd.LocalizedValue; localizedValue = dmd.LocalizedValue;
} }
@@ -169,16 +181,4 @@ public enum FridgeFreezerChannelSelector implements ApplianceChannelSelector {
return UnDefType.UNDEF; return UnDefType.UNDEF;
} }
} }
public String getMieleEnum(String s, DeviceMetaData dmd) {
if (dmd.MieleEnum != null) {
for (Entry<String, JsonElement> enumEntry : dmd.MieleEnum.entrySet()) {
if (enumEntry.getValue().getAsString().trim().equals(s.trim())) {
return enumEntry.getKey();
}
}
}
return null;
}
} }

View File

@@ -15,6 +15,8 @@ package org.openhab.binding.miele.internal.handler;
import static org.openhab.binding.miele.internal.MieleBindingConstants.*; import static org.openhab.binding.miele.internal.MieleBindingConstants.*;
import org.openhab.binding.miele.internal.handler.MieleBridgeHandler.DeviceProperty; import org.openhab.binding.miele.internal.handler.MieleBridgeHandler.DeviceProperty;
import org.openhab.core.i18n.LocaleProvider;
import org.openhab.core.i18n.TranslationProvider;
import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.OnOffType;
import org.openhab.core.thing.ChannelUID; import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing; import org.openhab.core.thing.Thing;
@@ -37,8 +39,9 @@ public class FridgeFreezerHandler extends MieleApplianceHandler<FridgeFreezerCha
private final Logger logger = LoggerFactory.getLogger(FridgeFreezerHandler.class); private final Logger logger = LoggerFactory.getLogger(FridgeFreezerHandler.class);
public FridgeFreezerHandler(Thing thing) { public FridgeFreezerHandler(Thing thing, TranslationProvider i18nProvider, LocaleProvider localeProvider) {
super(thing, FridgeFreezerChannelSelector.class, MIELE_DEVICE_CLASS_FRIDGE_FREEZER); super(thing, i18nProvider, localeProvider, FridgeFreezerChannelSelector.class,
MIELE_DEVICE_CLASS_FRIDGE_FREEZER);
} }
@Override @Override

View File

@@ -15,6 +15,8 @@ package org.openhab.binding.miele.internal.handler;
import static org.openhab.binding.miele.internal.MieleBindingConstants.*; import static org.openhab.binding.miele.internal.MieleBindingConstants.*;
import org.openhab.binding.miele.internal.handler.MieleBridgeHandler.DeviceProperty; import org.openhab.binding.miele.internal.handler.MieleBridgeHandler.DeviceProperty;
import org.openhab.core.i18n.LocaleProvider;
import org.openhab.core.i18n.TranslationProvider;
import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.OnOffType;
import org.openhab.core.thing.ChannelUID; import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing; import org.openhab.core.thing.Thing;
@@ -38,8 +40,8 @@ public class FridgeHandler extends MieleApplianceHandler<FridgeChannelSelector>
private final Logger logger = LoggerFactory.getLogger(FridgeHandler.class); private final Logger logger = LoggerFactory.getLogger(FridgeHandler.class);
public FridgeHandler(Thing thing) { public FridgeHandler(Thing thing, TranslationProvider i18nProvider, LocaleProvider localeProvider) {
super(thing, FridgeChannelSelector.class, MIELE_DEVICE_CLASS_FRIDGE); super(thing, i18nProvider, localeProvider, FridgeChannelSelector.class, MIELE_DEVICE_CLASS_FRIDGE);
} }
@Override @Override

View File

@@ -15,9 +15,10 @@ package org.openhab.binding.miele.internal.handler;
import static org.openhab.binding.miele.internal.MieleBindingConstants.*; import static org.openhab.binding.miele.internal.MieleBindingConstants.*;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Map.Entry;
import org.openhab.binding.miele.internal.handler.MieleBridgeHandler.DeviceMetaData; import org.openhab.binding.miele.internal.DeviceMetaData;
import org.openhab.binding.miele.internal.DeviceUtil;
import org.openhab.binding.miele.internal.MieleTranslationProvider;
import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.StringType; import org.openhab.core.library.types.StringType;
import org.openhab.core.types.State; import org.openhab.core.types.State;
@@ -25,8 +26,6 @@ import org.openhab.core.types.Type;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.google.gson.JsonElement;
/** /**
* The {@link ApplianceChannelSelector} for hobs * The {@link ApplianceChannelSelector} for hobs
* *
@@ -37,13 +36,22 @@ public enum HobChannelSelector implements ApplianceChannelSelector {
PRODUCT_TYPE("productTypeId", "productType", StringType.class, true), PRODUCT_TYPE("productTypeId", "productType", StringType.class, true),
DEVICE_TYPE("mieleDeviceType", "deviceType", StringType.class, true), DEVICE_TYPE("mieleDeviceType", "deviceType", StringType.class, true),
STATE_TEXT(STATE_PROPERTY_NAME, STATE_TEXT_CHANNEL_ID, StringType.class, false), STATE_TEXT(STATE_PROPERTY_NAME, STATE_TEXT_CHANNEL_ID, StringType.class, false) {
@Override
public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
State state = DeviceUtil.getStateTextState(s, dmd, translationProvider);
if (state != null) {
return state;
}
return super.getState(s, dmd, translationProvider);
}
},
STATE(null, STATE_CHANNEL_ID, DecimalType.class, false), STATE(null, STATE_CHANNEL_ID, DecimalType.class, false),
PLATES("plateNumbers", "plates", DecimalType.class, true), PLATES("plateNumbers", "plates", DecimalType.class, true),
PLATE1_POWER("plate1PowerStep", "plate1power", DecimalType.class, false), PLATE1_POWER("plate1PowerStep", "plate1power", DecimalType.class, false),
PLATE1_HEAT("plate1RemainingHeat", "plate1heat", DecimalType.class, false) { PLATE1_HEAT("plate1RemainingHeat", "plate1heat", DecimalType.class, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
// If there is remaining heat, the device metadata contains some informative string which can not be // If there is remaining heat, the device metadata contains some informative string which can not be
// converted into a DecimalType. We therefore ignore the metadata and return the device property value as a // converted into a DecimalType. We therefore ignore the metadata and return the device property value as a
// State // State
@@ -54,7 +62,7 @@ public enum HobChannelSelector implements ApplianceChannelSelector {
PLATE2_POWER("plate2PowerStep", "plate2power", DecimalType.class, false), PLATE2_POWER("plate2PowerStep", "plate2power", DecimalType.class, false),
PLATE2_HEAT("plate2RemainingHeat", "plate2heat", DecimalType.class, false) { PLATE2_HEAT("plate2RemainingHeat", "plate2heat", DecimalType.class, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
return getState(s); return getState(s);
} }
}, },
@@ -62,7 +70,7 @@ public enum HobChannelSelector implements ApplianceChannelSelector {
PLATE3_POWER("plate3PowerStep", "plate3power", DecimalType.class, false), PLATE3_POWER("plate3PowerStep", "plate3power", DecimalType.class, false),
PLATE3_HEAT("plate3RemainingHeat", "plate3heat", DecimalType.class, false) { PLATE3_HEAT("plate3RemainingHeat", "plate3heat", DecimalType.class, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
return getState(s); return getState(s);
} }
}, },
@@ -70,7 +78,7 @@ public enum HobChannelSelector implements ApplianceChannelSelector {
PLATE4_POWER("plate4PowerStep", "plate4power", DecimalType.class, false), PLATE4_POWER("plate4PowerStep", "plate4power", DecimalType.class, false),
PLATE4_HEAT("plate4RemainingHeat", "plate4heat", DecimalType.class, false) { PLATE4_HEAT("plate4RemainingHeat", "plate4heat", DecimalType.class, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
return getState(s); return getState(s);
} }
}, },
@@ -78,7 +86,7 @@ public enum HobChannelSelector implements ApplianceChannelSelector {
PLATE5_POWER("plate5PowerStep", "plate5power", DecimalType.class, false), PLATE5_POWER("plate5PowerStep", "plate5power", DecimalType.class, false),
PLATE5_HEAT("plate5RemainingHeat", "plate5heat", DecimalType.class, false) { PLATE5_HEAT("plate5RemainingHeat", "plate5heat", DecimalType.class, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
return getState(s); return getState(s);
} }
}, },
@@ -86,7 +94,7 @@ public enum HobChannelSelector implements ApplianceChannelSelector {
PLATE6_POWER("plate6PowerStep", "plate6power", DecimalType.class, false), PLATE6_POWER("plate6PowerStep", "plate6power", DecimalType.class, false),
PLATE6_HEAT("plate6RemainingHeat", "plate6heat", DecimalType.class, false) { PLATE6_HEAT("plate6RemainingHeat", "plate6heat", DecimalType.class, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
return getState(s); return getState(s);
} }
}, },
@@ -131,10 +139,15 @@ public enum HobChannelSelector implements ApplianceChannelSelector {
return false; return false;
} }
@Override
public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
return this.getState(s, dmd);
}
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd) {
if (dmd != null) { if (dmd != null) {
String localizedValue = getMieleEnum(s, dmd); String localizedValue = dmd.getMieleEnum(s);
if (localizedValue == null) { if (localizedValue == null) {
localizedValue = dmd.LocalizedValue; localizedValue = dmd.LocalizedValue;
} }
@@ -161,16 +174,4 @@ public enum HobChannelSelector implements ApplianceChannelSelector {
return null; return null;
} }
public String getMieleEnum(String s, DeviceMetaData dmd) {
if (dmd.MieleEnum != null) {
for (Entry<String, JsonElement> enumEntry : dmd.MieleEnum.entrySet()) {
if (enumEntry.getValue().getAsString().trim().equals(s.trim())) {
return enumEntry.getKey();
}
}
}
return null;
}
} }

View File

@@ -14,6 +14,8 @@ package org.openhab.binding.miele.internal.handler;
import static org.openhab.binding.miele.internal.MieleBindingConstants.MIELE_DEVICE_CLASS_HOB; import static org.openhab.binding.miele.internal.MieleBindingConstants.MIELE_DEVICE_CLASS_HOB;
import org.openhab.core.i18n.LocaleProvider;
import org.openhab.core.i18n.TranslationProvider;
import org.openhab.core.thing.ChannelUID; import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing; import org.openhab.core.thing.Thing;
import org.openhab.core.types.Command; import org.openhab.core.types.Command;
@@ -27,8 +29,8 @@ import org.openhab.core.types.Command;
*/ */
public class HobHandler extends MieleApplianceHandler<HobChannelSelector> { public class HobHandler extends MieleApplianceHandler<HobChannelSelector> {
public HobHandler(Thing thing) { public HobHandler(Thing thing, TranslationProvider i18nProvider, LocaleProvider localeProvider) {
super(thing, HobChannelSelector.class, MIELE_DEVICE_CLASS_HOB); super(thing, i18nProvider, localeProvider, HobChannelSelector.class, MIELE_DEVICE_CLASS_HOB);
} }
@Override @Override

View File

@@ -15,9 +15,10 @@ package org.openhab.binding.miele.internal.handler;
import static org.openhab.binding.miele.internal.MieleBindingConstants.*; import static org.openhab.binding.miele.internal.MieleBindingConstants.*;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Map.Entry;
import org.openhab.binding.miele.internal.handler.MieleBridgeHandler.DeviceMetaData; import org.openhab.binding.miele.internal.DeviceMetaData;
import org.openhab.binding.miele.internal.DeviceUtil;
import org.openhab.binding.miele.internal.MieleTranslationProvider;
import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.StringType; import org.openhab.core.library.types.StringType;
@@ -27,8 +28,6 @@ import org.openhab.core.types.UnDefType;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.google.gson.JsonElement;
/** /**
* The {@link ApplianceChannelSelector} for ventilation hoods * The {@link ApplianceChannelSelector} for ventilation hoods
* *
@@ -39,13 +38,22 @@ public enum HoodChannelSelector implements ApplianceChannelSelector {
PRODUCT_TYPE("productTypeId", "productType", StringType.class, true), PRODUCT_TYPE("productTypeId", "productType", StringType.class, true),
DEVICE_TYPE("mieleDeviceType", "deviceType", StringType.class, true), DEVICE_TYPE("mieleDeviceType", "deviceType", StringType.class, true),
STATE_TEXT(STATE_PROPERTY_NAME, STATE_TEXT_CHANNEL_ID, StringType.class, false), STATE_TEXT(STATE_PROPERTY_NAME, STATE_TEXT_CHANNEL_ID, StringType.class, false) {
@Override
public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
State state = DeviceUtil.getStateTextState(s, dmd, translationProvider);
if (state != null) {
return state;
}
return super.getState(s, dmd, translationProvider);
}
},
STATE(null, STATE_CHANNEL_ID, DecimalType.class, false), STATE(null, STATE_CHANNEL_ID, DecimalType.class, false),
VENTILATION("ventilationPower", "ventilation", DecimalType.class, false), VENTILATION("ventilationPower", "ventilation", DecimalType.class, false),
LIGHT("lightingStatus", "light", OnOffType.class, false) { LIGHT("lightingStatus", "light", OnOffType.class, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
if ("true".equals(s)) { if ("true".equals(s)) {
return getState("ON"); return getState("ON");
} }
@@ -98,10 +106,15 @@ public enum HoodChannelSelector implements ApplianceChannelSelector {
return false; return false;
} }
@Override
public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
return this.getState(s, dmd);
}
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd) {
if (dmd != null) { if (dmd != null) {
String localizedValue = getMieleEnum(s, dmd); String localizedValue = dmd.getMieleEnum(s);
if (localizedValue == null) { if (localizedValue == null) {
localizedValue = dmd.LocalizedValue; localizedValue = dmd.LocalizedValue;
} }
@@ -128,16 +141,4 @@ public enum HoodChannelSelector implements ApplianceChannelSelector {
return null; return null;
} }
public String getMieleEnum(String s, DeviceMetaData dmd) {
if (dmd.MieleEnum != null) {
for (Entry<String, JsonElement> enumEntry : dmd.MieleEnum.entrySet()) {
if (enumEntry.getValue().getAsString().trim().equals(s.trim())) {
return enumEntry.getKey();
}
}
}
return null;
}
} }

View File

@@ -15,6 +15,8 @@ package org.openhab.binding.miele.internal.handler;
import static org.openhab.binding.miele.internal.MieleBindingConstants.APPLIANCE_ID; import static org.openhab.binding.miele.internal.MieleBindingConstants.APPLIANCE_ID;
import static org.openhab.binding.miele.internal.MieleBindingConstants.MIELE_DEVICE_CLASS_HOOD; import static org.openhab.binding.miele.internal.MieleBindingConstants.MIELE_DEVICE_CLASS_HOOD;
import org.openhab.core.i18n.LocaleProvider;
import org.openhab.core.i18n.TranslationProvider;
import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.OnOffType;
import org.openhab.core.thing.ChannelUID; import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing; import org.openhab.core.thing.Thing;
@@ -37,8 +39,8 @@ public class HoodHandler extends MieleApplianceHandler<HoodChannelSelector> {
private final Logger logger = LoggerFactory.getLogger(HoodHandler.class); private final Logger logger = LoggerFactory.getLogger(HoodHandler.class);
public HoodHandler(Thing thing) { public HoodHandler(Thing thing, TranslationProvider i18nProvider, LocaleProvider localeProvider) {
super(thing, HoodChannelSelector.class, MIELE_DEVICE_CLASS_HOOD); super(thing, i18nProvider, localeProvider, HoodChannelSelector.class, MIELE_DEVICE_CLASS_HOOD);
} }
@Override @Override

View File

@@ -15,18 +15,23 @@ package org.openhab.binding.miele.internal.handler;
import static org.openhab.binding.miele.internal.MieleBindingConstants.*; import static org.openhab.binding.miele.internal.MieleBindingConstants.*;
import java.util.HashMap; import java.util.HashMap;
import java.util.IllformedLocaleException;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.NonNull;
import org.openhab.binding.miele.internal.DeviceMetaData;
import org.openhab.binding.miele.internal.DeviceUtil; import org.openhab.binding.miele.internal.DeviceUtil;
import org.openhab.binding.miele.internal.FullyQualifiedApplianceIdentifier; import org.openhab.binding.miele.internal.FullyQualifiedApplianceIdentifier;
import org.openhab.binding.miele.internal.MieleTranslationProvider;
import org.openhab.binding.miele.internal.handler.MieleBridgeHandler.DeviceClassObject; import org.openhab.binding.miele.internal.handler.MieleBridgeHandler.DeviceClassObject;
import org.openhab.binding.miele.internal.handler.MieleBridgeHandler.DeviceMetaData;
import org.openhab.binding.miele.internal.handler.MieleBridgeHandler.DeviceProperty; import org.openhab.binding.miele.internal.handler.MieleBridgeHandler.DeviceProperty;
import org.openhab.binding.miele.internal.handler.MieleBridgeHandler.HomeDevice; import org.openhab.binding.miele.internal.handler.MieleBridgeHandler.HomeDevice;
import org.openhab.core.i18n.LocaleProvider;
import org.openhab.core.i18n.TranslationProvider;
import org.openhab.core.thing.Bridge; import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.ChannelUID; import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing; import org.openhab.core.thing.Thing;
@@ -71,13 +76,19 @@ public abstract class MieleApplianceHandler<E extends Enum<E> & ApplianceChannel
protected String applianceId; protected String applianceId;
protected MieleBridgeHandler bridgeHandler; protected MieleBridgeHandler bridgeHandler;
protected TranslationProvider i18nProvider;
protected LocaleProvider localeProvider;
protected MieleTranslationProvider translationProvider;
private Class<E> selectorType; private Class<E> selectorType;
protected String modelID; protected String modelID;
protected Map<String, String> metaDataCache = new HashMap<>(); protected Map<String, String> metaDataCache = new HashMap<>();
public MieleApplianceHandler(Thing thing, Class<E> selectorType, String modelID) { public MieleApplianceHandler(Thing thing, TranslationProvider i18nProvider, LocaleProvider localeProvider,
Class<E> selectorType, String modelID) {
super(thing); super(thing);
this.i18nProvider = i18nProvider;
this.localeProvider = localeProvider;
this.selectorType = selectorType; this.selectorType = selectorType;
this.modelID = modelID; this.modelID = modelID;
} }
@@ -129,6 +140,25 @@ public abstract class MieleApplianceHandler<E extends Enum<E> & ApplianceChannel
if (bridge != null && getMieleBridgeHandler() != null) { if (bridge != null && getMieleBridgeHandler() != null) {
ThingStatusInfo statusInfo = bridge.getStatusInfo(); ThingStatusInfo statusInfo = bridge.getStatusInfo();
updateStatus(statusInfo.getStatus(), statusInfo.getStatusDetail(), statusInfo.getDescription()); updateStatus(statusInfo.getStatus(), statusInfo.getStatusDetail(), statusInfo.getDescription());
initializeTranslationProvider(bridge);
}
}
private void initializeTranslationProvider(Bridge bridge) {
Locale locale = null;
String language = (String) bridge.getConfiguration().get(LANGUAGE);
if (language != null && !language.isBlank()) {
try {
locale = new Locale.Builder().setLanguageTag(language).build();
} catch (IllformedLocaleException e) {
logger.error("Invalid language configured: {}", e.getMessage());
}
}
if (locale == null) {
logger.debug("No language configured, using system language.");
this.translationProvider = new MieleTranslationProvider(i18nProvider, localeProvider);
} else {
this.translationProvider = new MieleTranslationProvider(i18nProvider, localeProvider, locale);
} }
} }
@@ -240,7 +270,7 @@ public abstract class MieleApplianceHandler<E extends Enum<E> & ApplianceChannel
ChannelUID theChannelUID = new ChannelUID(getThing().getUID(), selector.getChannelID()); ChannelUID theChannelUID = new ChannelUID(getThing().getUID(), selector.getChannelID());
if (dp.Value != null) { if (dp.Value != null) {
State state = selector.getState(dpValue, dmd); State state = selector.getState(dpValue, dmd, this.translationProvider);
logger.trace("Update state of {} with getState '{}'", theChannelUID, state); logger.trace("Update state of {} with getState '{}'", theChannelUID, state);
updateState(theChannelUID, state); updateState(theChannelUID, state);
updateRawChannel(dp.Name, dpValue); updateRawChannel(dp.Name, dpValue);
@@ -249,10 +279,11 @@ public abstract class MieleApplianceHandler<E extends Enum<E> & ApplianceChannel
} }
} else { } else {
logger.debug("Updating the property '{}' of '{}' to '{}'", selector.getChannelID(), logger.debug("Updating the property '{}' of '{}' to '{}'", selector.getChannelID(),
getThing().getUID(), selector.getState(dpValue, dmd).toString()); getThing().getUID(), selector.getState(dpValue, dmd, this.translationProvider).toString());
@NonNull @NonNull
Map<@NonNull String, @NonNull String> properties = editProperties(); Map<@NonNull String, @NonNull String> properties = editProperties();
properties.put(selector.getChannelID(), selector.getState(dpValue, dmd).toString()); properties.put(selector.getChannelID(),
selector.getState(dpValue, dmd, this.translationProvider).toString());
updateProperties(properties); updateProperties(properties);
} }
} }

View File

@@ -31,8 +31,10 @@ import java.net.UnknownHostException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.IllformedLocaleException;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Random; import java.util.Random;
@@ -50,6 +52,7 @@ import java.util.zip.GZIPInputStream;
import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.NonNull;
import org.openhab.binding.miele.internal.FullyQualifiedApplianceIdentifier; import org.openhab.binding.miele.internal.FullyQualifiedApplianceIdentifier;
import org.openhab.core.common.NamedThreadFactory; import org.openhab.core.common.NamedThreadFactory;
import org.openhab.core.config.core.Configuration;
import org.openhab.core.thing.Bridge; import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.ChannelUID; import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing; import org.openhab.core.thing.Thing;
@@ -209,15 +212,6 @@ public class MieleBridgeHandler extends BaseBridgeHandler {
} }
} }
public class DeviceMetaData {
public String Filter;
public String description;
public String LocalizedID;
public String LocalizedValue;
public JsonObject MieleEnum;
public String access;
}
public MieleBridgeHandler(Bridge bridge) { public MieleBridgeHandler(Bridge bridge) {
super(bridge); super(bridge);
} }
@@ -226,31 +220,59 @@ public class MieleBridgeHandler extends BaseBridgeHandler {
public void initialize() { public void initialize() {
logger.debug("Initializing the Miele bridge handler."); logger.debug("Initializing the Miele bridge handler.");
if (getConfig().get(HOST) != null && getConfig().get(INTERFACE) != null) { if (!validateConfig(getConfig())) {
if (IP_PATTERN.matcher((String) getConfig().get(HOST)).matches() return;
&& IP_PATTERN.matcher((String) getConfig().get(INTERFACE)).matches()) {
try {
url = new URL("http://" + (String) getConfig().get(HOST) + "/remote/json-rpc");
} catch (MalformedURLException e) {
logger.debug("An exception occurred while defining an URL :'{}'", e.getMessage());
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.CONFIGURATION_ERROR, e.getMessage());
return;
}
// for future usage - no headers to be set for now
headers = new HashMap<>();
onUpdate();
updateStatus(ThingStatus.UNKNOWN);
} else {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.CONFIGURATION_ERROR,
"Invalid IP address for the Miele@Home gateway or multicast interface:" + getConfig().get(HOST)
+ "/" + getConfig().get(INTERFACE));
}
} else {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.CONFIGURATION_ERROR,
"Cannot connect to the Miele gateway. host IP address or multicast interface are not set.");
} }
try {
url = new URL("http://" + (String) getConfig().get(HOST) + "/remote/json-rpc");
} catch (MalformedURLException e) {
logger.debug("An exception occurred while defining an URL :'{}'", e.getMessage());
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.CONFIGURATION_ERROR, e.getMessage());
return;
}
// for future usage - no headers to be set for now
headers = new HashMap<>();
onUpdate();
lastBridgeConnectionState = false;
updateStatus(ThingStatus.UNKNOWN);
}
private boolean validateConfig(Configuration config) {
if (config.get(HOST) == null || ((String) config.get(HOST)).isBlank()) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.CONFIGURATION_ERROR,
"@text/offline.configuration-error.ip-address-not-set");
return false;
}
if (config.get(INTERFACE) == null || ((String) config.get(INTERFACE)).isBlank()) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.CONFIGURATION_ERROR,
"@text/offline.configuration-error.ip-multicast-interface-not-set");
return false;
}
if (!IP_PATTERN.matcher((String) config.get(HOST)).matches()) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.CONFIGURATION_ERROR,
"@text/offline.configuration-error.invalid-ip-gateway [\"" + config.get(HOST) + "\"]");
return false;
}
if (!IP_PATTERN.matcher((String) config.get(INTERFACE)).matches()) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.CONFIGURATION_ERROR,
"@text/offline.configuration-error.invalid-ip-multicast-interface [\"" + config.get(INTERFACE)
+ "\"]");
return false;
}
String language = (String) config.get(LANGUAGE);
if (language != null && !language.isBlank()) {
try {
new Locale.Builder().setLanguageTag(language).build();
} catch (IllformedLocaleException e) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.CONFIGURATION_ERROR,
"@text/offline.configuration-error.invalid-language [\"" + language + "\"]");
return false;
}
}
return true;
} }
private Runnable pollingRunnable = new Runnable() { private Runnable pollingRunnable = new Runnable() {

View File

@@ -19,11 +19,11 @@ import java.lang.reflect.Method;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.TimeZone; import java.util.TimeZone;
import org.openhab.binding.miele.internal.DeviceMetaData;
import org.openhab.binding.miele.internal.DeviceUtil; import org.openhab.binding.miele.internal.DeviceUtil;
import org.openhab.binding.miele.internal.handler.MieleBridgeHandler.DeviceMetaData; import org.openhab.binding.miele.internal.MieleTranslationProvider;
import org.openhab.core.library.types.DateTimeType; import org.openhab.core.library.types.DateTimeType;
import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.OnOffType;
@@ -36,8 +36,6 @@ import org.openhab.core.types.UnDefType;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.google.gson.JsonElement;
/** /**
* The {@link ApplianceChannelSelector} for ovens * The {@link ApplianceChannelSelector} for ovens
* *
@@ -49,25 +47,35 @@ public enum OvenChannelSelector implements ApplianceChannelSelector {
PRODUCT_TYPE("productTypeId", "productType", StringType.class, true), PRODUCT_TYPE("productTypeId", "productType", StringType.class, true),
DEVICE_TYPE("mieleDeviceType", "deviceType", StringType.class, true), DEVICE_TYPE("mieleDeviceType", "deviceType", StringType.class, true),
STATE_TEXT(STATE_PROPERTY_NAME, STATE_TEXT_CHANNEL_ID, StringType.class, false), STATE_TEXT(STATE_PROPERTY_NAME, STATE_TEXT_CHANNEL_ID, StringType.class, false) {
@Override
public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
State state = DeviceUtil.getStateTextState(s, dmd, translationProvider);
if (state != null) {
return state;
}
return super.getState(s, dmd, translationProvider);
}
},
STATE(null, STATE_CHANNEL_ID, DecimalType.class, false), STATE(null, STATE_CHANNEL_ID, DecimalType.class, false),
PROGRAM_TEXT(PROGRAM_ID_PROPERTY_NAME, PROGRAM_TEXT_CHANNEL_ID, StringType.class, false), PROGRAM_TEXT(PROGRAM_ID_PROPERTY_NAME, PROGRAM_TEXT_CHANNEL_ID, StringType.class, false),
PROGRAM(null, PROGRAM_CHANNEL_ID, DecimalType.class, false), PROGRAM(null, PROGRAM_CHANNEL_ID, DecimalType.class, false),
PROGRAMTYPE("programType", "type", StringType.class, false), PROGRAMTYPE("programType", "type", StringType.class, false),
PROGRAM_PHASE_TEXT(PHASE_PROPERTY_NAME, PHASE_TEXT_CHANNEL_ID, StringType.class, false) { PROGRAM_PHASE_TEXT(PHASE_PROPERTY_NAME, PHASE_TEXT_CHANNEL_ID, StringType.class, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
State state = getTextState(s, dmd, phases, MISSING_PHASE_TEXT_PREFIX); State state = DeviceUtil.getTextState(s, dmd, translationProvider, phases, MISSING_PHASE_TEXT_PREFIX,
MIELE_OVEN_TEXT_PREFIX);
if (state != null) { if (state != null) {
return state; return state;
} }
return super.getState(s, dmd); return super.getState(s, dmd, translationProvider);
} }
}, },
PROGRAM_PHASE(RAW_PHASE_PROPERTY_NAME, PHASE_CHANNEL_ID, DecimalType.class, false), PROGRAM_PHASE(RAW_PHASE_PROPERTY_NAME, PHASE_CHANNEL_ID, DecimalType.class, false),
START_TIME("startTime", "start", DateTimeType.class, false) { START_TIME("startTime", "start", DateTimeType.class, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
Date date = new Date(); Date date = new Date();
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT+0")); dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT+0"));
@@ -81,7 +89,7 @@ public enum OvenChannelSelector implements ApplianceChannelSelector {
}, },
DURATION("duration", "duration", DateTimeType.class, false) { DURATION("duration", "duration", DateTimeType.class, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
Date date = new Date(); Date date = new Date();
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT+0")); dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT+0"));
@@ -95,7 +103,7 @@ public enum OvenChannelSelector implements ApplianceChannelSelector {
}, },
ELAPSED_TIME("elapsedTime", "elapsed", DateTimeType.class, false) { ELAPSED_TIME("elapsedTime", "elapsed", DateTimeType.class, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
Date date = new Date(); Date date = new Date();
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT+0")); dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT+0"));
@@ -109,7 +117,7 @@ public enum OvenChannelSelector implements ApplianceChannelSelector {
}, },
FINISH_TIME("finishTime", "finish", DateTimeType.class, false) { FINISH_TIME("finishTime", "finish", DateTimeType.class, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
Date date = new Date(); Date date = new Date();
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT+0")); dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT+0"));
@@ -123,32 +131,32 @@ public enum OvenChannelSelector implements ApplianceChannelSelector {
}, },
TARGET_TEMP("targetTemperature", "target", QuantityType.class, false) { TARGET_TEMP("targetTemperature", "target", QuantityType.class, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
return getTemperatureState(s); return getTemperatureState(s);
} }
}, },
MEASURED_TEMP("measuredTemperature", "measured", QuantityType.class, false) { MEASURED_TEMP("measuredTemperature", "measured", QuantityType.class, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
return getTemperatureState(s); return getTemperatureState(s);
} }
}, },
DEVICE_TEMP_ONE("deviceTemperature1", "temp1", QuantityType.class, false) { DEVICE_TEMP_ONE("deviceTemperature1", "temp1", QuantityType.class, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
return getTemperatureState(s); return getTemperatureState(s);
} }
}, },
DEVICE_TEMP_TWO("deviceTemperature2", "temp2", QuantityType.class, false) { DEVICE_TEMP_TWO("deviceTemperature2", "temp2", QuantityType.class, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
return getTemperatureState(s); return getTemperatureState(s);
} }
}, },
DOOR("signalDoor", "door", OpenClosedType.class, false) { DOOR("signalDoor", "door", OpenClosedType.class, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
if ("true".equals(s)) { if ("true".equals(s)) {
return getState("OPEN"); return getState("OPEN");
} }
@@ -165,9 +173,9 @@ public enum OvenChannelSelector implements ApplianceChannelSelector {
private final Logger logger = LoggerFactory.getLogger(OvenChannelSelector.class); private final Logger logger = LoggerFactory.getLogger(OvenChannelSelector.class);
private static final Map<String, String> phases = Map.ofEntries(entry("1", "Heating"), entry("2", "Temp. hold"), private static final Map<String, String> phases = Map.ofEntries(entry("1", "heating"), entry("2", "temp-hold"),
entry("3", "Door Open"), entry("4", "Pyrolysis"), entry("7", "Lighting"), entry("8", "Searing phase"), entry("3", "door-open"), entry("4", "pyrolysis"), entry("7", "lighting"), entry("8", "searing-phase"),
entry("10", "Defrost"), entry("11", "Cooling down"), entry("12", "Energy save phase")); entry("10", "defrost"), entry("11", "cooling-down"), entry("12", "energy-save-phase"));
private final String mieleID; private final String mieleID;
private final String channelID; private final String channelID;
@@ -206,10 +214,15 @@ public enum OvenChannelSelector implements ApplianceChannelSelector {
return false; return false;
} }
@Override
public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
return this.getState(s, dmd);
}
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd) {
if (dmd != null) { if (dmd != null) {
String localizedValue = getMieleEnum(s, dmd); String localizedValue = dmd.getMieleEnum(s);
if (localizedValue == null) { if (localizedValue == null) {
localizedValue = dmd.LocalizedValue; localizedValue = dmd.LocalizedValue;
} }
@@ -245,34 +258,4 @@ public enum OvenChannelSelector implements ApplianceChannelSelector {
return UnDefType.UNDEF; return UnDefType.UNDEF;
} }
} }
public State getTextState(String s, DeviceMetaData dmd, Map<String, String> valueMap, String prefix) {
if ("0".equals(s)) {
return UnDefType.UNDEF;
}
if (dmd == null || dmd.LocalizedValue == null || dmd.LocalizedValue.startsWith(prefix)) {
String text = valueMap.get(s);
if (text != null) {
return getState(text);
}
if (dmd == null || dmd.LocalizedValue == null) {
return getState(prefix + s);
}
}
return null;
}
public String getMieleEnum(String s, DeviceMetaData dmd) {
if (dmd.MieleEnum != null) {
for (Entry<String, JsonElement> enumEntry : dmd.MieleEnum.entrySet()) {
if (enumEntry.getValue().getAsString().trim().equals(s.trim())) {
return enumEntry.getKey();
}
}
}
return null;
}
} }

View File

@@ -15,6 +15,8 @@ package org.openhab.binding.miele.internal.handler;
import static org.openhab.binding.miele.internal.MieleBindingConstants.APPLIANCE_ID; import static org.openhab.binding.miele.internal.MieleBindingConstants.APPLIANCE_ID;
import static org.openhab.binding.miele.internal.MieleBindingConstants.MIELE_DEVICE_CLASS_OVEN; import static org.openhab.binding.miele.internal.MieleBindingConstants.MIELE_DEVICE_CLASS_OVEN;
import org.openhab.core.i18n.LocaleProvider;
import org.openhab.core.i18n.TranslationProvider;
import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.OnOffType;
import org.openhab.core.thing.ChannelUID; import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing; import org.openhab.core.thing.Thing;
@@ -38,8 +40,8 @@ public class OvenHandler extends MieleApplianceHandler<OvenChannelSelector> {
private final Logger logger = LoggerFactory.getLogger(OvenHandler.class); private final Logger logger = LoggerFactory.getLogger(OvenHandler.class);
public OvenHandler(Thing thing) { public OvenHandler(Thing thing, TranslationProvider i18nProvider, LocaleProvider localeProvider) {
super(thing, OvenChannelSelector.class, MIELE_DEVICE_CLASS_OVEN); super(thing, i18nProvider, localeProvider, OvenChannelSelector.class, MIELE_DEVICE_CLASS_OVEN);
} }
@Override @Override

View File

@@ -19,10 +19,11 @@ import java.lang.reflect.Method;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.TimeZone; import java.util.TimeZone;
import org.openhab.binding.miele.internal.handler.MieleBridgeHandler.DeviceMetaData; import org.openhab.binding.miele.internal.DeviceMetaData;
import org.openhab.binding.miele.internal.DeviceUtil;
import org.openhab.binding.miele.internal.MieleTranslationProvider;
import org.openhab.core.library.types.DateTimeType; import org.openhab.core.library.types.DateTimeType;
import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.OnOffType;
@@ -34,8 +35,6 @@ import org.openhab.core.types.UnDefType;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.google.gson.JsonElement;
/** /**
* The {@link ApplianceChannelSelector} for tumble dryers * The {@link ApplianceChannelSelector} for tumble dryers
* *
@@ -47,34 +46,45 @@ public enum TumbleDryerChannelSelector implements ApplianceChannelSelector {
PRODUCT_TYPE("productTypeId", "productType", StringType.class, true), PRODUCT_TYPE("productTypeId", "productType", StringType.class, true),
DEVICE_TYPE("mieleDeviceType", "deviceType", StringType.class, true), DEVICE_TYPE("mieleDeviceType", "deviceType", StringType.class, true),
STATE_TEXT(STATE_PROPERTY_NAME, STATE_TEXT_CHANNEL_ID, StringType.class, false), STATE_TEXT(STATE_PROPERTY_NAME, STATE_TEXT_CHANNEL_ID, StringType.class, false) {
STATE(null, STATE_CHANNEL_ID, DecimalType.class, false),
PROGRAM_TEXT(PROGRAM_ID_PROPERTY_NAME, PROGRAM_TEXT_CHANNEL_ID, StringType.class, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
State state = getTextState(s, dmd, programs, MISSING_PROGRAM_TEXT_PREFIX); State state = DeviceUtil.getStateTextState(s, dmd, translationProvider);
if (state != null) { if (state != null) {
return state; return state;
} }
return super.getState(s, dmd); return super.getState(s, dmd, translationProvider);
}
},
STATE(null, STATE_CHANNEL_ID, DecimalType.class, false),
PROGRAM_TEXT(PROGRAM_ID_PROPERTY_NAME, PROGRAM_TEXT_CHANNEL_ID, StringType.class, false) {
@Override
public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
State state = DeviceUtil.getTextState(s, dmd, translationProvider, programs, MISSING_PROGRAM_TEXT_PREFIX,
MIELE_TUMBLE_DRYER_TEXT_PREFIX);
if (state != null) {
return state;
}
return super.getState(s, dmd, translationProvider);
} }
}, },
PROGRAM(null, PROGRAM_CHANNEL_ID, DecimalType.class, false), PROGRAM(null, PROGRAM_CHANNEL_ID, DecimalType.class, false),
PROGRAMTYPE("programType", "type", StringType.class, false), PROGRAMTYPE("programType", "type", StringType.class, false),
PROGRAM_PHASE_TEXT(PHASE_PROPERTY_NAME, PHASE_TEXT_CHANNEL_ID, StringType.class, false) { PROGRAM_PHASE_TEXT(PHASE_PROPERTY_NAME, PHASE_TEXT_CHANNEL_ID, StringType.class, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
State state = getTextState(s, dmd, phases, MISSING_PHASE_TEXT_PREFIX); State state = DeviceUtil.getTextState(s, dmd, translationProvider, phases, MISSING_PHASE_TEXT_PREFIX,
MIELE_TUMBLE_DRYER_TEXT_PREFIX);
if (state != null) { if (state != null) {
return state; return state;
} }
return super.getState(s, dmd); return super.getState(s, dmd, translationProvider);
} }
}, },
PROGRAM_PHASE(RAW_PHASE_PROPERTY_NAME, PHASE_CHANNEL_ID, DecimalType.class, false), PROGRAM_PHASE(RAW_PHASE_PROPERTY_NAME, PHASE_CHANNEL_ID, DecimalType.class, false),
START_TIME("startTime", "start", DateTimeType.class, false) { START_TIME("startTime", "start", DateTimeType.class, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
Date date = new Date(); Date date = new Date();
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT+0")); dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT+0"));
@@ -88,7 +98,7 @@ public enum TumbleDryerChannelSelector implements ApplianceChannelSelector {
}, },
DURATION("duration", "duration", DateTimeType.class, false) { DURATION("duration", "duration", DateTimeType.class, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
Date date = new Date(); Date date = new Date();
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT+0")); dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT+0"));
@@ -102,7 +112,7 @@ public enum TumbleDryerChannelSelector implements ApplianceChannelSelector {
}, },
ELAPSED_TIME("elapsedTime", "elapsed", DateTimeType.class, false) { ELAPSED_TIME("elapsedTime", "elapsed", DateTimeType.class, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
Date date = new Date(); Date date = new Date();
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT+0")); dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT+0"));
@@ -116,7 +126,7 @@ public enum TumbleDryerChannelSelector implements ApplianceChannelSelector {
}, },
FINISH_TIME("finishTime", "finish", DateTimeType.class, false) { FINISH_TIME("finishTime", "finish", DateTimeType.class, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
Date date = new Date(); Date date = new Date();
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT+0")); dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT+0"));
@@ -130,14 +140,14 @@ public enum TumbleDryerChannelSelector implements ApplianceChannelSelector {
}, },
DRYING_STEP("dryingStep", "step", DecimalType.class, false) { DRYING_STEP("dryingStep", "step", DecimalType.class, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
return getState(s); return getState(s);
} }
}, },
DOOR("signalDoor", "door", OpenClosedType.class, false) { DOOR("signalDoor", "door", OpenClosedType.class, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
if ("true".equals(s)) { if ("true".equals(s)) {
return getState("OPEN"); return getState("OPEN");
} }
@@ -153,20 +163,20 @@ public enum TumbleDryerChannelSelector implements ApplianceChannelSelector {
private final Logger logger = LoggerFactory.getLogger(TumbleDryerChannelSelector.class); private final Logger logger = LoggerFactory.getLogger(TumbleDryerChannelSelector.class);
private static final Map<String, String> programs = Map.ofEntries(entry("10", "Automatic Plus"), private static final Map<String, String> programs = Map.ofEntries(entry("10", "automatic-plus"),
entry("23", "Cottons hygiene"), entry("30", "Minimum iron"), entry("31", "Gentle minimum iron"), entry("20", "cottons"), entry("23", "cottons-hygiene"), entry("30", "minimum-iron"),
entry("40", "Woollens handcare"), entry("50", "Delicates"), entry("60", "Warm Air"), entry("31", "gentle-minimum-iron"), entry("40", "woollens-handcare"), entry("50", "delicates"),
entry("70", "Cool air"), entry("80", "Express"), entry("90", "Cottons"), entry("100", "Gentle smoothing"), entry("60", "warm-air"), entry("70", "cool-air"), entry("80", "express"), entry("90", "cottons-eco"),
entry("120", "Proofing"), entry("130", "Denim"), entry("131", "Gentle denim"), entry("140", "Shirts"), entry("100", "gentle-smoothing"), entry("120", "proofing"), entry("130", "denim"),
entry("141", "Gentle shirts"), entry("150", "Sportswear"), entry("160", "Outerwear"), entry("131", "gentle-denim"), entry("140", "shirts"), entry("141", "gentle-shirts"),
entry("170", "Silks handcare"), entry("190", "Standard pillows"), entry("220", "Basket programme"), entry("150", "sportswear"), entry("160", "outerwear"), entry("170", "silks-handcare"),
entry("240", "Smoothing"), entry("65000", "Cottons, auto load control"), entry("190", "standard-pillows"), entry("220", "basket-programme"), entry("240", "smoothing"),
entry("65001", "Minimum iron, auto load control")); entry("65000", "cottons-auto-load-control"), entry("65001", "minimum-iron-auto-load-control"));
private static final Map<String, String> phases = Map.ofEntries(entry("1", "Programme running"), private static final Map<String, String> phases = Map.ofEntries(entry("1", "programme-running"),
entry("2", "Drying"), entry("3", "Drying Machine iron"), entry("4", "Drying Hand iron"), entry("2", "drying"), entry("3", "drying-machine-iron"), entry("4", "drying-hand-iron"),
entry("5", "Drying Normal"), entry("6", "Drying Normal+"), entry("7", "Cooling down"), entry("5", "drying-normal"), entry("6", "drying-normal-plus"), entry("7", "cooling-down"),
entry("8", "Drying Hand iron"), entry("10", "Finished")); entry("8", "drying-hand-iron"), entry("10", "finished"));
private final String mieleID; private final String mieleID;
private final String channelID; private final String channelID;
@@ -206,10 +216,15 @@ public enum TumbleDryerChannelSelector implements ApplianceChannelSelector {
return false; return false;
} }
@Override
public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
return this.getState(s, dmd);
}
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd) {
if (dmd != null) { if (dmd != null) {
String localizedValue = getMieleEnum(s, dmd); String localizedValue = dmd.getMieleEnum(s);
if (localizedValue == null) { if (localizedValue == null) {
localizedValue = dmd.LocalizedValue; localizedValue = dmd.LocalizedValue;
} }
@@ -236,34 +251,4 @@ public enum TumbleDryerChannelSelector implements ApplianceChannelSelector {
return null; return null;
} }
public State getTextState(String s, DeviceMetaData dmd, Map<String, String> valueMap, String prefix) {
if ("0".equals(s)) {
return UnDefType.UNDEF;
}
if (dmd == null || dmd.LocalizedValue == null || dmd.LocalizedValue.startsWith(prefix)) {
String text = valueMap.get(s);
if (text != null) {
return getState(text);
}
if (dmd == null || dmd.LocalizedValue == null) {
return getState(prefix + s);
}
}
return null;
}
public String getMieleEnum(String s, DeviceMetaData dmd) {
if (dmd.MieleEnum != null) {
for (Entry<String, JsonElement> enumEntry : dmd.MieleEnum.entrySet()) {
if (enumEntry.getValue().getAsString().trim().equals(s.trim())) {
return enumEntry.getKey();
}
}
}
return null;
}
} }

View File

@@ -15,6 +15,8 @@ package org.openhab.binding.miele.internal.handler;
import static org.openhab.binding.miele.internal.MieleBindingConstants.APPLIANCE_ID; import static org.openhab.binding.miele.internal.MieleBindingConstants.APPLIANCE_ID;
import static org.openhab.binding.miele.internal.MieleBindingConstants.MIELE_DEVICE_CLASS_TUMBLE_DRYER; import static org.openhab.binding.miele.internal.MieleBindingConstants.MIELE_DEVICE_CLASS_TUMBLE_DRYER;
import org.openhab.core.i18n.LocaleProvider;
import org.openhab.core.i18n.TranslationProvider;
import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.OnOffType;
import org.openhab.core.thing.ChannelUID; import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing; import org.openhab.core.thing.Thing;
@@ -38,8 +40,8 @@ public class TumbleDryerHandler extends MieleApplianceHandler<TumbleDryerChannel
private final Logger logger = LoggerFactory.getLogger(TumbleDryerHandler.class); private final Logger logger = LoggerFactory.getLogger(TumbleDryerHandler.class);
public TumbleDryerHandler(Thing thing) { public TumbleDryerHandler(Thing thing, TranslationProvider i18nProvider, LocaleProvider localeProvider) {
super(thing, TumbleDryerChannelSelector.class, MIELE_DEVICE_CLASS_TUMBLE_DRYER); super(thing, i18nProvider, localeProvider, TumbleDryerChannelSelector.class, MIELE_DEVICE_CLASS_TUMBLE_DRYER);
} }
@Override @Override

View File

@@ -19,11 +19,11 @@ import java.lang.reflect.Method;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.TimeZone; import java.util.TimeZone;
import org.openhab.binding.miele.internal.DeviceMetaData;
import org.openhab.binding.miele.internal.DeviceUtil; import org.openhab.binding.miele.internal.DeviceUtil;
import org.openhab.binding.miele.internal.handler.MieleBridgeHandler.DeviceMetaData; import org.openhab.binding.miele.internal.MieleTranslationProvider;
import org.openhab.core.library.types.DateTimeType; import org.openhab.core.library.types.DateTimeType;
import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.OnOffType;
@@ -36,8 +36,6 @@ import org.openhab.core.types.UnDefType;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.google.gson.JsonElement;
/** /**
* The {@link ApplianceChannelSelector} for washing machines * The {@link ApplianceChannelSelector} for washing machines
* *
@@ -49,34 +47,45 @@ public enum WashingMachineChannelSelector implements ApplianceChannelSelector {
PRODUCT_TYPE("productTypeId", "productType", StringType.class, true, false), PRODUCT_TYPE("productTypeId", "productType", StringType.class, true, false),
DEVICE_TYPE("mieleDeviceType", "deviceType", StringType.class, true, false), DEVICE_TYPE("mieleDeviceType", "deviceType", StringType.class, true, false),
STATE_TEXT(STATE_PROPERTY_NAME, STATE_TEXT_CHANNEL_ID, StringType.class, false, false), STATE_TEXT(STATE_PROPERTY_NAME, STATE_TEXT_CHANNEL_ID, StringType.class, false, false) {
STATE(null, STATE_CHANNEL_ID, DecimalType.class, false, false),
PROGRAM_TEXT(PROGRAM_ID_PROPERTY_NAME, PROGRAM_TEXT_CHANNEL_ID, StringType.class, false, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
State state = getTextState(s, dmd, programs, MISSING_PROGRAM_TEXT_PREFIX); State state = DeviceUtil.getStateTextState(s, dmd, translationProvider);
if (state != null) { if (state != null) {
return state; return state;
} }
return super.getState(s, dmd); return super.getState(s, dmd, translationProvider);
}
},
STATE(null, STATE_CHANNEL_ID, DecimalType.class, false, false),
PROGRAM_TEXT(PROGRAM_ID_PROPERTY_NAME, PROGRAM_TEXT_CHANNEL_ID, StringType.class, false, false) {
@Override
public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
State state = DeviceUtil.getTextState(s, dmd, translationProvider, programs, MISSING_PROGRAM_TEXT_PREFIX,
MIELE_WASHING_MACHINE_TEXT_PREFIX);
if (state != null) {
return state;
}
return super.getState(s, dmd, translationProvider);
} }
}, },
PROGRAM(null, PROGRAM_CHANNEL_ID, DecimalType.class, false, false), PROGRAM(null, PROGRAM_CHANNEL_ID, DecimalType.class, false, false),
PROGRAMTYPE("programType", "type", StringType.class, false, false), PROGRAMTYPE("programType", "type", StringType.class, false, false),
PROGRAM_PHASE_TEXT(PHASE_PROPERTY_NAME, PHASE_TEXT_CHANNEL_ID, StringType.class, false, false) { PROGRAM_PHASE_TEXT(PHASE_PROPERTY_NAME, PHASE_TEXT_CHANNEL_ID, StringType.class, false, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
State state = getTextState(s, dmd, phases, MISSING_PHASE_TEXT_PREFIX); State state = DeviceUtil.getTextState(s, dmd, translationProvider, phases, MISSING_PHASE_TEXT_PREFIX,
MIELE_WASHING_MACHINE_TEXT_PREFIX);
if (state != null) { if (state != null) {
return state; return state;
} }
return super.getState(s, dmd); return super.getState(s, dmd, translationProvider);
} }
}, },
PROGRAM_PHASE(RAW_PHASE_PROPERTY_NAME, PHASE_CHANNEL_ID, DecimalType.class, false, false), PROGRAM_PHASE(RAW_PHASE_PROPERTY_NAME, PHASE_CHANNEL_ID, DecimalType.class, false, false),
START_TIME("startTime", "start", DateTimeType.class, false, false) { START_TIME("startTime", "start", DateTimeType.class, false, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
Date date = new Date(); Date date = new Date();
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT+0")); dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT+0"));
@@ -90,7 +99,7 @@ public enum WashingMachineChannelSelector implements ApplianceChannelSelector {
}, },
DURATION("duration", "duration", DateTimeType.class, false, false) { DURATION("duration", "duration", DateTimeType.class, false, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
Date date = new Date(); Date date = new Date();
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT+0")); dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT+0"));
@@ -104,7 +113,7 @@ public enum WashingMachineChannelSelector implements ApplianceChannelSelector {
}, },
ELAPSED_TIME("elapsedTime", "elapsed", DateTimeType.class, false, false) { ELAPSED_TIME("elapsedTime", "elapsed", DateTimeType.class, false, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
Date date = new Date(); Date date = new Date();
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT+0")); dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT+0"));
@@ -118,7 +127,7 @@ public enum WashingMachineChannelSelector implements ApplianceChannelSelector {
}, },
FINISH_TIME("finishTime", "finish", DateTimeType.class, false, false) { FINISH_TIME("finishTime", "finish", DateTimeType.class, false, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
Date date = new Date(); Date date = new Date();
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT+0")); dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT+0"));
@@ -132,13 +141,13 @@ public enum WashingMachineChannelSelector implements ApplianceChannelSelector {
}, },
TARGET_TEMP("targetTemperature", "target", QuantityType.class, false, false) { TARGET_TEMP("targetTemperature", "target", QuantityType.class, false, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
return getTemperatureState(s); return getTemperatureState(s);
} }
}, },
SPINNING_SPEED("spinningSpeed", "spinningspeed", StringType.class, false, false) { SPINNING_SPEED("spinningSpeed", "spinningspeed", StringType.class, false, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
if ("0".equals(s)) { if ("0".equals(s)) {
return getState("Without spinning"); return getState("Without spinning");
} }
@@ -151,7 +160,7 @@ public enum WashingMachineChannelSelector implements ApplianceChannelSelector {
DOOR("signalDoor", "door", OpenClosedType.class, false, false) { DOOR("signalDoor", "door", OpenClosedType.class, false, false) {
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
if ("true".equals(s)) { if ("true".equals(s)) {
return getState("OPEN"); return getState("OPEN");
} }
@@ -171,18 +180,18 @@ public enum WashingMachineChannelSelector implements ApplianceChannelSelector {
private final Logger logger = LoggerFactory.getLogger(WashingMachineChannelSelector.class); private final Logger logger = LoggerFactory.getLogger(WashingMachineChannelSelector.class);
private static final Map<String, String> programs = Map.ofEntries(entry("1", "Cottons"), entry("3", "Minimum iron"), private static final Map<String, String> programs = Map.ofEntries(entry("1", "cottons"), entry("3", "minimum-iron"),
entry("4", "Delicates"), entry("8", "Woollens"), entry("9", "Silks"), entry("17", "Starch"), entry("4", "delicates"), entry("8", "woollens"), entry("9", "silks"), entry("17", "starch"),
entry("18", "Rinse"), entry("21", "Drain/Spin"), entry("22", "Curtains"), entry("23", "Shirts"), entry("18", "rinse"), entry("21", "drain-spin"), entry("22", "curtains"), entry("23", "shirts"),
entry("24", "Denim"), entry("27", "Proofing"), entry("29", "Sportswear"), entry("31", "Automatic Plus"), entry("24", "denim"), entry("27", "proofing"), entry("29", "sportswear"), entry("31", "automatic-plus"),
entry("37", "Outerwear"), entry("39", "Pillows"), entry("50", "Dark Garments"), entry("53", "First wash"), entry("37", "outerwear"), entry("39", "pillows"), entry("50", "dark-garments"), entry("53", "first-wash"),
entry("75", "Steam care"), entry("76", "Freshen up"), entry("91", "Maintenance wash"), entry("75", "steam-care"), entry("76", "freshen-up"), entry("91", "maintenance-wash"),
entry("95", "Down duvets"), entry("122", "Express 20"), entry("129", "Down filled items"), entry("95", "down-duvets"), entry("122", "express-20"), entry("129", "down-filled-items"),
entry("133", "Cottons Eco"), entry("146", "QuickPowerWash"), entry("65532", "Mix")); entry("133", "cottons-eco"), entry("146", "quickpowerwash"), entry("65532", "mix"));
private static final Map<String, String> phases = Map.ofEntries(entry("1", "Pre-wash"), entry("4", "Washing"), private static final Map<String, String> phases = Map.ofEntries(entry("1", "pre-wash"), entry("4", "washing"),
entry("5", "Rinses"), entry("7", "Clean"), entry("9", "Drain"), entry("10", "Spin"), entry("5", "rinses"), entry("7", "clean"), entry("9", "drain"), entry("10", "spin"),
entry("11", "Anti-crease"), entry("12", "Finished")); entry("11", "anti-crease"), entry("12", "finished"));
private final String mieleID; private final String mieleID;
private final String channelID; private final String channelID;
@@ -224,10 +233,15 @@ public enum WashingMachineChannelSelector implements ApplianceChannelSelector {
return isExtendedState; return isExtendedState;
} }
@Override
public State getState(String s, DeviceMetaData dmd, MieleTranslationProvider translationProvider) {
return this.getState(s, dmd);
}
@Override @Override
public State getState(String s, DeviceMetaData dmd) { public State getState(String s, DeviceMetaData dmd) {
if (dmd != null) { if (dmd != null) {
String localizedValue = getMieleEnum(s, dmd); String localizedValue = dmd.getMieleEnum(s);
if (localizedValue == null) { if (localizedValue == null) {
localizedValue = dmd.LocalizedValue; localizedValue = dmd.LocalizedValue;
} }
@@ -263,34 +277,4 @@ public enum WashingMachineChannelSelector implements ApplianceChannelSelector {
return UnDefType.UNDEF; return UnDefType.UNDEF;
} }
} }
public State getTextState(String s, DeviceMetaData dmd, Map<String, String> valueMap, String prefix) {
if ("0".equals(s)) {
return UnDefType.UNDEF;
}
if (dmd == null || dmd.LocalizedValue == null || dmd.LocalizedValue.startsWith(prefix)) {
String text = valueMap.get(s);
if (text != null) {
return getState(text);
}
if (dmd == null || dmd.LocalizedValue == null) {
return getState(prefix + s);
}
}
return null;
}
public String getMieleEnum(String s, DeviceMetaData dmd) {
if (dmd.MieleEnum != null) {
for (Entry<String, JsonElement> enumEntry : dmd.MieleEnum.entrySet()) {
if (enumEntry.getValue().getAsString().trim().equals(s.trim())) {
return enumEntry.getKey();
}
}
}
return null;
}
} }

View File

@@ -19,6 +19,8 @@ import static org.openhab.binding.miele.internal.MieleBindingConstants.WATER_CON
import java.math.BigDecimal; import java.math.BigDecimal;
import org.openhab.core.i18n.LocaleProvider;
import org.openhab.core.i18n.TranslationProvider;
import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.QuantityType; import org.openhab.core.library.types.QuantityType;
import org.openhab.core.library.unit.Units; import org.openhab.core.library.unit.Units;
@@ -49,8 +51,9 @@ public class WashingMachineHandler extends MieleApplianceHandler<WashingMachineC
private final Logger logger = LoggerFactory.getLogger(WashingMachineHandler.class); private final Logger logger = LoggerFactory.getLogger(WashingMachineHandler.class);
public WashingMachineHandler(Thing thing) { public WashingMachineHandler(Thing thing, TranslationProvider i18nProvider, LocaleProvider localeProvider) {
super(thing, WashingMachineChannelSelector.class, MIELE_DEVICE_CLASS_WASHING_MACHINE); super(thing, i18nProvider, localeProvider, WashingMachineChannelSelector.class,
MIELE_DEVICE_CLASS_WASHING_MACHINE);
} }
@Override @Override

View File

@@ -11,18 +11,33 @@ thing-type.miele.dishwasher.label = Dishwasher
thing-type.miele.dishwasher.description = This is a Miele@home compatible dishwasher thing-type.miele.dishwasher.description = This is a Miele@home compatible dishwasher
thing-type.miele.fridge.label = Fridge thing-type.miele.fridge.label = Fridge
thing-type.miele.fridge.description = This is a Miele@home compatible fridge thing-type.miele.fridge.description = This is a Miele@home compatible fridge
thing-type.miele.fridge.channel.current.description = Current temperature in the fridge
thing-type.miele.fridge.channel.target.description = Target temperature to be reached by the fridge
thing-type.miele.fridgefreezer.label = Fridge Freezer thing-type.miele.fridgefreezer.label = Fridge Freezer
thing-type.miele.fridgefreezer.description = This is a Miele@home compatible fridgefreezer thing-type.miele.fridgefreezer.description = This is a Miele@home compatible fridgefreezer
thing-type.miele.fridgefreezer.channel.freezercurrent.description = Current temperature in the freezer compartment
thing-type.miele.fridgefreezer.channel.freezertarget.description = Target temperature to be reached by the freezer compartment
thing-type.miele.fridgefreezer.channel.fridgecurrent.description = Current temperature in the fridge compartment
thing-type.miele.fridgefreezer.channel.fridgetarget.description = Target temperature to be reached by the fridge compartment
thing-type.miele.hob.label = Hob thing-type.miele.hob.label = Hob
thing-type.miele.hob.description = This is a Miele@home compatible hob thing-type.miele.hob.description = This is a Miele@home compatible hob
thing-type.miele.hood.label = Hood thing-type.miele.hood.label = Hood
thing-type.miele.hood.description = This is a Miele@home compatible hood thing-type.miele.hood.description = This is a Miele@home compatible hood
thing-type.miele.oven.label = Oven thing-type.miele.oven.label = Oven
thing-type.miele.oven.description = This is a Miele@home compatible oven thing-type.miele.oven.description = This is a Miele@home compatible oven
thing-type.miele.oven.channel.measured.label = Measured Temperature
thing-type.miele.oven.channel.measured.description = Actual measured temperature in the oven
thing-type.miele.oven.channel.target.description = Target temperature to be reached by the oven
thing-type.miele.oven.channel.temp1.label = Program Temperature 1
thing-type.miele.oven.channel.temp1.description = Program temperature in the oven
thing-type.miele.oven.channel.temp2.label = Program Temperature 2
thing-type.miele.oven.channel.temp2.description = Program temperature in the oven
thing-type.miele.tumbledryer.label = Tumbledryer thing-type.miele.tumbledryer.label = Tumbledryer
thing-type.miele.tumbledryer.description = This is a Miele@home compatible tumbledryer thing-type.miele.tumbledryer.description = This is a Miele@home compatible tumbledryer
thing-type.miele.washingmachine.label = Washing Machine thing-type.miele.washingmachine.label = Washing Machine
thing-type.miele.washingmachine.description = This is a Miele@home compatible washing machine thing-type.miele.washingmachine.description = This is a Miele@home compatible washing machine
thing-type.miele.washingmachine.channel.target.label = Temperature
thing-type.miele.washingmachine.channel.target.description = Temperature of the selected program (10 °C = cold)
thing-type.miele.xgw3000.label = Miele XGW3000 thing-type.miele.xgw3000.label = Miele XGW3000
thing-type.miele.xgw3000.description = The Miele bridge represents the Miele@home XGW3000 gateway. thing-type.miele.xgw3000.description = The Miele bridge represents the Miele@home XGW3000 gateway.
@@ -34,6 +49,8 @@ thing-type.config.miele.xgw3000.interface.label = Network Address of the Multica
thing-type.config.miele.xgw3000.interface.description = Network address of openHAB host interface where the binding will listen for multicast events coming from the Miele@home gateway. thing-type.config.miele.xgw3000.interface.description = Network address of openHAB host interface where the binding will listen for multicast events coming from the Miele@home gateway.
thing-type.config.miele.xgw3000.ipAddress.label = Network Address thing-type.config.miele.xgw3000.ipAddress.label = Network Address
thing-type.config.miele.xgw3000.ipAddress.description = Network address of the Miele@home gateway. thing-type.config.miele.xgw3000.ipAddress.description = Network address of the Miele@home gateway.
thing-type.config.miele.xgw3000.language.label = Language
thing-type.config.miele.xgw3000.language.description = Language for state, program and phase texts. Leave blank for system language.
thing-type.config.miele.xgw3000.password.label = Password thing-type.config.miele.xgw3000.password.label = Password
thing-type.config.miele.xgw3000.password.description = Password for the registered Miele@home user. thing-type.config.miele.xgw3000.password.description = Password for the registered Miele@home user.
thing-type.config.miele.xgw3000.userName.label = Username thing-type.config.miele.xgw3000.userName.label = Username
@@ -105,3 +122,137 @@ channel-type.miele.ventilation.label = Ventilation Power
channel-type.miele.ventilation.description = Current ventilation power channel-type.miele.ventilation.description = Current ventilation power
channel-type.miele.waterConsumption.label = Water Consumption channel-type.miele.waterConsumption.label = Water Consumption
channel-type.miele.waterConsumption.description = Water consumption by the currently running program on the appliance channel-type.miele.waterConsumption.description = Water consumption by the currently running program on the appliance
# thing status descriptions
offline.configuration-error.ip-address-not-set = Cannot connect to the Miele gateway: host IP address is not set.
offline.configuration-error.ip-multicast-interface-not-set = Cannot connect to the Miele gateway: multicast interface is not set.
offline.configuration-error.invalid-ip-gateway = Invalid IP address for the Miele@Home gateway: {0}
offline.configuration-error.invalid-ip-multicast-interface = Invalid IP address for the multicast interface: {0}
offline.configuration-error.invalid-language = Invalid language: {0}
# miele states
miele.state.off = Off
miele.state.stand-by = Stand-by
miele.state.programmed = Programmed
miele.state.waiting-to-start = Waiting to Start
miele.state.running = Running
miele.state.paused = Paused
miele.state.end = End
miele.state.failure = Failure
miele.state.abort = Abort
miele.state.idle = Idle
miele.state.rinse-hold = Rinse Hold
miele.state.service = Service
miele.state.super-freezing = Super Freezing
miele.state.super-cooling = Super Cooling
miele.state.super-heating = Super Heating
miele.state.default = Default
miele.state.locked = Locked
miele.state.not-connected = Not Connected
# miele programs
miele.program.dishwasher.intensive = Intensive
miele.program.dishwasher.maintenance-programme = Maintenance programme
miele.program.dishwasher.eco = ECO
miele.program.dishwasher.normal = Normal
miele.program.dishwasher.automatic = Automatic
miele.program.dishwasher.solarsave = SolarSave
miele.program.dishwasher.gentle = Gentle
miele.program.dishwasher.extra-quiet = Extra Quiet
miele.program.dishwasher.hygiene = Hygiene
miele.program.dishwasher.quickpowerwash = QuickPowerWash
miele.program.dishwasher.tall-items = Tall items
miele.program.tumbledryer.automatic-plus = Automatic Plus
miele.program.tumbledryer.cottons = Cottons
miele.program.tumbledryer.cottons-hygiene = Cottons hygiene
miele.program.tumbledryer.minimum-iron = Minimum iron
miele.program.tumbledryer.gentle-minimum-iron = Gentle minimum iron
miele.program.tumbledryer.woollens-handcare = Woollens handcare
miele.program.tumbledryer.delicates = Delicates
miele.program.tumbledryer.warm-air = Warm Air
miele.program.tumbledryer.cool-air = Cool air
miele.program.tumbledryer.express = Express
miele.program.tumbledryer.cottons-eco = Cottons Eco
miele.program.tumbledryer.gentle-smoothing = Gentle smoothing
miele.program.tumbledryer.proofing = Proofing
miele.program.tumbledryer.denim = Denim
miele.program.tumbledryer.gentle-denim = Gentle denim
miele.program.tumbledryer.shirts = Shirts
miele.program.tumbledryer.gentle-shirts = Gentle shirts
miele.program.tumbledryer.sportswear = Sportswear
miele.program.tumbledryer.outerwear = Outerwear
miele.program.tumbledryer.silks-handcare = Silks handcare
miele.program.tumbledryer.standard-pillows = Standard pillows
miele.program.tumbledryer.basket-programme = Basket programme
miele.program.tumbledryer.smoothing = Smoothing
miele.program.tumbledryer.cottons-auto-load-control = Cottons, auto load control
miele.program.tumbledryer.minimum-iron-auto-load-control = Minimum iron, auto load control
miele.program.washingmachine.cottons = Cottons
miele.program.washingmachine.minimum-iron = Minimum iron
miele.program.washingmachine.delicates = Delicates
miele.program.washingmachine.woollens = Woollens
miele.program.washingmachine.silks = Silks
miele.program.washingmachine.starch = Starch
miele.program.washingmachine.rinse = Rinse
miele.program.washingmachine.drain-spin = Drain/Spin
miele.program.washingmachine.curtains = Curtains
miele.program.washingmachine.shirts = Shirts
miele.program.washingmachine.denim = Denim
miele.program.washingmachine.proofing = Proofing
miele.program.washingmachine.sportswear = Sportswear
miele.program.washingmachine.automatic-plus = Automatic Plus
miele.program.washingmachine.outerwear = Outerwear
miele.program.washingmachine.pillows = Pillows
miele.program.washingmachine.dark-garments = Dark Garments
miele.program.washingmachine.first-wash = First wash
miele.program.washingmachine.steam-care = Steam care
miele.program.washingmachine.freshen-up = Freshen up
miele.program.washingmachine.maintenance-wash = Maintenance wash
miele.program.washingmachine.down-duvets = Down duvets
miele.program.washingmachine.express-20 = Express 20
miele.program.washingmachine.down-filled-items = Down filled items
miele.program.washingmachine.cottons-eco = Cottons Eco
miele.program.washingmachine.quickpowerwash = QuickPowerWash
miele.program.washingmachine.mix = Mix
# miele phases
miele.phase.dishwasher.pre-wash = Pre-Wash
miele.phase.dishwasher.main-wash = Main Wash
miele.phase.dishwasher.rinses = Rinses
miele.phase.dishwasher.final-rinse = Final rinse
miele.phase.dishwasher.drying = Drying
miele.phase.dishwasher.finished = Finished
miele.phase.oven.heating = Heating
miele.phase.oven.temp-hold = Temp. hold
miele.phase.oven.door-open = Door Open
miele.phase.oven.pyrolysis = Pyrolysis
miele.phase.oven.lighting = Lighting
miele.phase.oven.searing-phase = Searing phase
miele.phase.oven.defrost = Defrost
miele.phase.oven.cooling-down = Cooling down
miele.phase.oven.energy-save-phase = Energy save phase
miele.phase.tumbledryer.programme-running = Programme running
miele.phase.tumbledryer.drying = Drying
miele.phase.tumbledryer.drying-machine-iron = Drying Machine iron
miele.phase.tumbledryer.drying-hand-iron = Drying Hand iron
miele.phase.tumbledryer.drying-normal = Drying Normal
miele.phase.tumbledryer.drying-normal-plus = Drying Normal+
miele.phase.tumbledryer.cooling-down = Cooling down
miele.phase.tumbledryer.finished = Finished
miele.phase.washingmachine.pre-wash = Pre-wash
miele.phase.washingmachine.washing = Washing
miele.phase.washingmachine.rinses = Rinses
miele.phase.washingmachine.clean = Clean
miele.phase.washingmachine.drain = Drain
miele.phase.washingmachine.spin = Spin
miele.phase.washingmachine.anti-crease = Anti-crease
miele.phase.washingmachine.finished = Finished

View File

@@ -11,18 +11,33 @@ thing-type.miele.dishwasher.label = Opvaskemaskine
thing-type.miele.dishwasher.description = Dette er en Miele@home-kompatibel opvaskemaskine thing-type.miele.dishwasher.description = Dette er en Miele@home-kompatibel opvaskemaskine
thing-type.miele.fridge.label = Køleskab thing-type.miele.fridge.label = Køleskab
thing-type.miele.fridge.description = Dette er et Miele@home-kompatibelt køleskab thing-type.miele.fridge.description = Dette er et Miele@home-kompatibelt køleskab
thing-type.miele.fridge.channel.current.description = Aktuel temperatur i køleskabet
thing-type.miele.fridge.channel.target.description = Måltemperatur der skal nås af køleskabet
thing-type.miele.fridgefreezer.label = Kølefryseskab thing-type.miele.fridgefreezer.label = Kølefryseskab
thing-type.miele.fridgefreezer.description = Dette er et Miele@home-kompatibelt kølefryseskab thing-type.miele.fridgefreezer.description = Dette er et Miele@home-kompatibelt kølefryseskab
thing-type.miele.fridgefreezer.channel.freezercurrent.description = Aktuel temperatur i fryserummet
thing-type.miele.fridgefreezer.channel.freezertarget.description = Måltemperatur der skal nås i fryserummet
thing-type.miele.fridgefreezer.channel.fridgecurrent.description = Aktuel temperatur i kølerummet
thing-type.miele.fridgefreezer.channel.fridgetarget.description = Måltemperatur der skal nås i kølerummet
thing-type.miele.hob.label = Kogeplader thing-type.miele.hob.label = Kogeplader
thing-type.miele.hob.description = Dette er Miele@home-kompatible kogeplader thing-type.miele.hob.description = Dette er Miele@home-kompatible kogeplader
thing-type.miele.hood.label = Emhætte thing-type.miele.hood.label = Emhætte
thing-type.miele.hood.description = Dette er en Miele@home-kompatibel emhætte thing-type.miele.hood.description = Dette er en Miele@home-kompatibel emhætte
thing-type.miele.oven.label = Ovn thing-type.miele.oven.label = Ovn
thing-type.miele.oven.description = Dette er en Miele@home-kompatibel ovn thing-type.miele.oven.description = Dette er en Miele@home-kompatibel ovn
thing-type.miele.oven.channel.measured.label = Målt temperatur
thing-type.miele.oven.channel.measured.description = Aktuel målt temperatur i ovnen
thing-type.miele.oven.channel.target.description = Måltemperatur der skal nås af ovnen
thing-type.miele.oven.channel.temp1.label = Programtemperatur 1
thing-type.miele.oven.channel.temp1.description = Programtemperatur i ovnen
thing-type.miele.oven.channel.temp2.label = Programtemperatur 2
thing-type.miele.oven.channel.temp2.description = Programtemperatur i ovnen
thing-type.miele.tumbledryer.label = Tørretumbler thing-type.miele.tumbledryer.label = Tørretumbler
thing-type.miele.tumbledryer.description = Dette er en Miele@home-kompatibel tørretumbler thing-type.miele.tumbledryer.description = Dette er en Miele@home-kompatibel tørretumbler
thing-type.miele.washingmachine.label = Vaskemaskine thing-type.miele.washingmachine.label = Vaskemaskine
thing-type.miele.washingmachine.description = Dette er en Miele@home-kompatibel vaskemaskine thing-type.miele.washingmachine.description = Dette er en Miele@home-kompatibel vaskemaskine
thing-type.miele.washingmachine.channel.target.label = Temperatur
thing-type.miele.washingmachine.channel.target.description = Temperatur for det valgte program (10 °C = koldt)
thing-type.miele.xgw3000.label = Miele XGW3000 thing-type.miele.xgw3000.label = Miele XGW3000
thing-type.miele.xgw3000.description = Miele-bridgen repræsenterer Miele@home XGW3000-gateway'en. thing-type.miele.xgw3000.description = Miele-bridgen repræsenterer Miele@home XGW3000-gateway'en.
@@ -34,7 +49,135 @@ thing-type.config.miele.xgw3000.interface.label = Netværksadresse til multicast
thing-type.config.miele.xgw3000.interface.description = Netværksadresse til openHAB værts-interfacet hvor bindingen vil lytte på multicast-hændelser fra Miele@home-gateway'en. thing-type.config.miele.xgw3000.interface.description = Netværksadresse til openHAB værts-interfacet hvor bindingen vil lytte på multicast-hændelser fra Miele@home-gateway'en.
thing-type.config.miele.xgw3000.ipAddress.label = Netværksadresse thing-type.config.miele.xgw3000.ipAddress.label = Netværksadresse
thing-type.config.miele.xgw3000.ipAddress.description = Netværksadresse til Miele@home-gateway'en. thing-type.config.miele.xgw3000.ipAddress.description = Netværksadresse til Miele@home-gateway'en.
thing-type.config.miele.xgw3000.language.label = Sprog
thing-type.config.miele.xgw3000.language.description = Sprog for tilstand-, program- og fasetekster. Efterlad feltet tomt for systemsprog.
thing-type.config.miele.xgw3000.password.label = Adgangskode thing-type.config.miele.xgw3000.password.label = Adgangskode
thing-type.config.miele.xgw3000.password.description = Adgangskode til registreret Miele@home-bruger. thing-type.config.miele.xgw3000.password.description = Adgangskode til registreret Miele@home-bruger.
thing-type.config.miele.xgw3000.userName.label = Brugernavn thing-type.config.miele.xgw3000.userName.label = Brugernavn
thing-type.config.miele.xgw3000.userName.description = Navn på en registeret Miele@home-bruger. thing-type.config.miele.xgw3000.userName.description = Navn på en registeret Miele@home-bruger.
# miele states
miele.state.off = Frakoblet
miele.state.stand-by = Tilkoblet
miele.state.programmed = Programmeret
miele.state.waiting-to-start = Udskudt start
miele.state.running = I brug
miele.state.paused = På pause
miele.state.end = Slut
miele.state.failure = Fejl
miele.state.abort = Afbrudt
miele.state.idle = Idle
miele.state.rinse-hold = Skyllestop
miele.state.service = Service
miele.state.super-freezing = Superfrys
miele.state.super-cooling = Superkøl
#miele.state.super-heating =
#miele.state.default
miele.state.locked = Låst
miele.state.not-connected = Ikke forbundet
# miele programs
miele.program.dishwasher.intensive = Intensiv
miele.program.dishwasher.maintenance-programme = Maskinrengøring
miele.program.dishwasher.eco = ECO
miele.program.dishwasher.normal = Universal+
miele.program.dishwasher.automatic = Automatic
miele.program.dishwasher.solarsave = SolarSpar
miele.program.dishwasher.gentle = Automatic skåne
miele.program.dishwasher.extra-quiet = Ekstra lydsvag
miele.program.dishwasher.hygiene = Hygiejne
miele.program.dishwasher.quickpowerwash = QuickPowerWash
miele.program.dishwasher.tall-items = Uden overkurv
miele.program.tumbledryer.automatic-plus = Automatic Plus
miele.program.tumbledryer.cottons = Bomuld
miele.program.tumbledryer.cottons-hygiene = Bomuld Allergi Plus
miele.program.tumbledryer.minimum-iron = Strygelet
miele.program.tumbledryer.gentle-minimum-iron = Strygelet, skånsom
miele.program.tumbledryer.woollens-handcare = Finish uld
miele.program.tumbledryer.delicates = Finvask
miele.program.tumbledryer.warm-air = Varm luft
miele.program.tumbledryer.cool-air = Kold luft
miele.program.tumbledryer.express = Ekspres
miele.program.tumbledryer.cottons-eco = Bomuld Eco
miele.program.tumbledryer.gentle-smoothing = Udglatning, skånsom
miele.program.tumbledryer.proofing = Imprægnering
miele.program.tumbledryer.denim = Denim
miele.program.tumbledryer.gentle-denim = Denim, skånsom
miele.program.tumbledryer.shirts = Skjorter
miele.program.tumbledryer.gentle-shirts = Skjorter, skånsom
miele.program.tumbledryer.sportswear = Sportstøj
miele.program.tumbledryer.outerwear = Outdoor
miele.program.tumbledryer.silks-handcare = Silke
miele.program.tumbledryer.standard-pillows = Hovedpuder
miele.program.tumbledryer.basket-programme = Tørrekurvprogram
miele.program.tumbledryer.smoothing = Dampudglatning
miele.program.tumbledryer.cottons-auto-load-control = Bomuld, mængdeautomatik
miele.program.tumbledryer.minimum-iron-auto-load-control = Strygelet, mængdeautomatik
miele.program.washingmachine.cottons = Bomuld
miele.program.washingmachine.minimum-iron = Strygelet
miele.program.washingmachine.delicates = Finvask
miele.program.washingmachine.woollens = Uld
miele.program.washingmachine.silks = Silke
miele.program.washingmachine.starch = Stivelse
miele.program.washingmachine.rinse = Kun skyl
miele.program.washingmachine.drain-spin = Pumpe/Centrifugering
miele.program.washingmachine.curtains = Gardiner
miele.program.washingmachine.shirts = Skjorter
miele.program.washingmachine.denim = Denim
miele.program.washingmachine.proofing = Imprægnering
miele.program.washingmachine.sportswear = Sportstøj
miele.program.washingmachine.automatic-plus = Automatic Plus
miele.program.washingmachine.outerwear = Outdoor
miele.program.washingmachine.pillows = Hovedpuder
miele.program.washingmachine.dark-garments = Mørkt
miele.program.washingmachine.first-wash = Nye tekstiler
miele.program.washingmachine.steam-care = Finish damp
miele.program.washingmachine.freshen-up = Opfriskning
miele.program.washingmachine.maintenance-wash = Maskine rengøres
miele.program.washingmachine.down-duvets = Fjer-/dundyner
miele.program.washingmachine.express-20 = Ekspres 20
miele.program.washingmachine.down-filled-items = Dun
miele.program.washingmachine.cottons-eco = Bomuld Eco
miele.program.washingmachine.quickpowerwash = QuickPowerWash
miele.program.washingmachine.mix = Mix
# miele phases
miele.phase.dishwasher.pre-wash = Forskyl
miele.phase.dishwasher.main-wash = Opvask
miele.phase.dishwasher.rinses = Skylning
miele.phase.dishwasher.final-rinse = Klarskyl
miele.phase.dishwasher.drying = Tørring
miele.phase.dishwasher.finished = Slut
miele.phase.oven.heating = Opvarmningsfase
miele.phase.oven.temp-hold = Tilberedning
miele.phase.oven.door-open = Dør åben
miele.phase.oven.pyrolysis = Pyrolyse
miele.phase.oven.lighting = Ovnlys
miele.phase.oven.searing-phase = Bruningsfase
miele.phase.oven.defrost = Optøning
miele.phase.oven.cooling-down = Afkøling
miele.phase.oven.energy-save-phase = Energisparefase
miele.phase.tumbledryer.programme-running = Program kører
miele.phase.tumbledryer.drying = Tørring
miele.phase.tumbledryer.drying-machine-iron = Rulletørt
miele.phase.tumbledryer.drying-hand-iron = Strygetørt
miele.phase.tumbledryer.drying-normal = Skabstørt
miele.phase.tumbledryer.drying-normal-plus = Skabstørt+
miele.phase.tumbledryer.cooling-down = Afkøling
miele.phase.tumbledryer.finished = Slut
miele.phase.washingmachine.pre-wash = Forvask
miele.phase.washingmachine.washing = Vask
miele.phase.washingmachine.rinses = Skylning
miele.phase.washingmachine.clean = Rengøring
miele.phase.washingmachine.drain = Udpumpning
miele.phase.washingmachine.spin = Centrifugering
miele.phase.washingmachine.anti-crease = Antikrøl
miele.phase.washingmachine.finished = Slut

View File

@@ -0,0 +1,125 @@
# miele states
miele.state.off = Aus
miele.state.stand-by = Bereit
miele.state.programmed = Programm gewählt
miele.state.waiting-to-start = Start verzögert
miele.state.running = In Betrieb
miele.state.paused = Pause
miele.state.end = Ende
#miele.state.failure =
miele.state.abort = Abbruch
#miele.state.idle =
#miele.state.rinse-hold =
#miele.state.service =
#miele.state.super-freezing =
miele.state.super-cooling = Superkühlen
#miele.state.super-heating =
#miele.state.default
#miele.state.locked =
#miele.state.not-connected =
# miele programs
miele.program.dishwasher.intensive = Intensiv
miele.program.dishwasher.maintenance-programme = Maschinenreinigung
miele.program.dishwasher.eco = ECO
miele.program.dishwasher.normal = Normal
miele.program.dishwasher.automatic = Automatic
miele.program.dishwasher.solarsave = SolarSpar
miele.program.dishwasher.gentle = Fein
miele.program.dishwasher.extra-quiet = Extra Leise
miele.program.dishwasher.hygiene = Hygiene
miele.program.dishwasher.quickpowerwash = QuickPowerWash
miele.program.dishwasher.tall-items = Ohne Oberkorb
miele.program.tumbledryer.automatic-plus = Automatic Plus
miele.program.tumbledryer.cottons = Baumwolle
miele.program.tumbledryer.cottons-hygiene = Baumwolle Hygiene
miele.program.tumbledryer.minimum-iron = Pflegeleicht
miele.program.tumbledryer.gentle-minimum-iron = Pflegeleicht
miele.program.tumbledryer.woollens-handcare = Finish Wolle
miele.program.tumbledryer.delicates = Feinwäsche
miele.program.tumbledryer.warm-air = Lüften warm
miele.program.tumbledryer.cool-air = Lüften kalt
miele.program.tumbledryer.express = Express
miele.program.tumbledryer.cottons-eco = Baumwolle ECO
miele.program.tumbledryer.gentle-smoothing = Schonglätten
miele.program.tumbledryer.proofing = Imprägnieren
miele.program.tumbledryer.denim = Jeans
miele.program.tumbledryer.gentle-denim = Jeans
miele.program.tumbledryer.shirts = Oberhemden
miele.program.tumbledryer.gentle-shirts = Oberhemden
miele.program.tumbledryer.sportswear = Sportwäsche
miele.program.tumbledryer.outerwear = Outdoor
miele.program.tumbledryer.silks-handcare = Finish Seide
miele.program.tumbledryer.standard-pillows = Kopfkissen normal
miele.program.tumbledryer.basket-programme = Korbprogramm
miele.program.tumbledryer.smoothing = Dampfglätten
miele.program.tumbledryer.cottons-auto-load-control = Baumwolle
miele.program.tumbledryer.minimum-iron-auto-load-control = Pflegeleicht
miele.program.washingmachine.cottons = Baumwolle
miele.program.washingmachine.minimum-iron = Pflegeleicht
miele.program.washingmachine.delicates = Feinwäsche
miele.program.washingmachine.woollens = Wolle
miele.program.washingmachine.silks = Seide
miele.program.washingmachine.starch = Stärken
miele.program.washingmachine.rinse = Nur spülen
miele.program.washingmachine.drain-spin = Pumpen/Schleudern
miele.program.washingmachine.curtains = Gardinen
miele.program.washingmachine.shirts = Oberhemden
miele.program.washingmachine.denim = Jeans
miele.program.washingmachine.proofing = Imprägnieren
miele.program.washingmachine.sportswear = Sportwäsche
miele.program.washingmachine.automatic-plus = Automatic plus
miele.program.washingmachine.outerwear = Outdoor
miele.program.washingmachine.pillows = Kopfkissen
miele.program.washingmachine.dark-garments = Dunkle Wäsche
miele.program.washingmachine.first-wash = Neue Textilien
miele.program.washingmachine.steam-care = Finish Dampf
miele.program.washingmachine.freshen-up = Auffrischen
miele.program.washingmachine.maintenance-wash = Maschine reinigen
miele.program.washingmachine.down-duvets = Federbetten
miele.program.washingmachine.express-20 = Express 20
miele.program.washingmachine.down-filled-items = Daunen
miele.program.washingmachine.cottons-eco = Baumwolle Eco
miele.program.washingmachine.quickpowerwash = QuickPowerWash
miele.program.washingmachine.mix = Einzelteilemix
# miele phases
miele.phase.dishwasher.pre-wash = Vorspülen
miele.phase.dishwasher.main-wash = Reinigen
miele.phase.dishwasher.rinses = Spülen
miele.phase.dishwasher.final-rinse = Klarspülen
miele.phase.dishwasher.drying = Trocknen
miele.phase.dishwasher.finished = Ende
miele.phase.oven.heating = Aufheizphase
miele.phase.oven.temp-hold = Garen
miele.phase.oven.door-open = Tür geöffnet
miele.phase.oven.pyrolysis = Pyrolyse
miele.phase.oven.lighting = Beleuchtung
miele.phase.oven.searing-phase = Anbratphase
miele.phase.oven.defrost = Auftauen
miele.phase.oven.cooling-down = Abkühlen
miele.phase.oven.energy-save-phase = Energiesparphase
miele.phase.tumbledryer.programme-running = Programm läuft
miele.phase.tumbledryer.drying = Trocknen
miele.phase.tumbledryer.drying-machine-iron = Mangelfeucht
miele.phase.tumbledryer.drying-hand-iron = Bügelfeucht
miele.phase.tumbledryer.drying-normal = Schranktrocken
miele.phase.tumbledryer.drying-normal-plus = Schranktrocken+
miele.phase.tumbledryer.cooling-down = Abkühlen
miele.phase.tumbledryer.finished = Ende
miele.phase.washingmachine.pre-wash = Vorwaschen
miele.phase.washingmachine.washing = Waschen
miele.phase.washingmachine.rinses = Spülen
miele.phase.washingmachine.clean = Reinigen
miele.phase.washingmachine.drain = Abpumpen
miele.phase.washingmachine.spin = Schleudern
miele.phase.washingmachine.anti-crease = Knitterschutz
miele.phase.washingmachine.finished = Ende

View File

@@ -0,0 +1,125 @@
# miele states
miele.state.off = Arrêt
miele.state.stand-by = Prêt
miele.state.programmed = Programme sélectionné
miele.state.waiting-to-start = Départ différé
miele.state.running = En cours de fonctionnement
miele.state.paused = Pause
miele.state.end = Fin
#miele.state.failure =
miele.state.abort = Interruption
#miele.state.idle =
#miele.state.rinse-hold =
#miele.state.service =
#miele.state.super-freezing =
miele.state.super-cooling = Superfroid
#miele.state.super-heating =
#miele.state.default =
#miele.state.locked =
#miele.state.not-connected =
# miele programs
miele.program.dishwasher.intensive = Intensif Plus
miele.program.dishwasher.maintenance-programme = Nettoyage machine
miele.program.dishwasher.eco = ECO
miele.program.dishwasher.normal = Quotidien
miele.program.dishwasher.automatic = Automatic
miele.program.dishwasher.solarsave = Economique Solaire
miele.program.dishwasher.gentle = Fragile
miele.program.dishwasher.extra-quiet = Extra silencieux
miele.program.dishwasher.hygiene = Hygiène
miele.program.dishwasher.quickpowerwash = QuickPowerWash
miele.program.dishwasher.tall-items = Volumineux
miele.program.tumbledryer.automatic-plus = Automatic plus
miele.program.tumbledryer.cottons = Coton
miele.program.tumbledryer.cottons-hygiene = Coton hygiène
miele.program.tumbledryer.minimum-iron = Synthétique
miele.program.tumbledryer.gentle-minimum-iron = Synthétique
miele.program.tumbledryer.woollens-handcare = Laine
miele.program.tumbledryer.delicates = Fin
miele.program.tumbledryer.warm-air = Air chaud
miele.program.tumbledryer.cool-air = Air froid
miele.program.tumbledryer.express = Express
miele.program.tumbledryer.cottons-eco = Coton éco
miele.program.tumbledryer.gentle-smoothing = Défroissage doux
miele.program.tumbledryer.proofing = Imperméabilisation
miele.program.tumbledryer.denim = Jeans
miele.program.tumbledryer.gentle-denim = Jeans
miele.program.tumbledryer.shirts = Chemises
miele.program.tumbledryer.gentle-shirts = Chemises
miele.program.tumbledryer.sportswear = Textiles sport
miele.program.tumbledryer.outerwear = Outdoor
miele.program.tumbledryer.silks-handcare = Finish soie
miele.program.tumbledryer.standard-pillows = Oreillers
miele.program.tumbledryer.basket-programme = Programme panier
miele.program.tumbledryer.smoothing = Défroissage vapeur
miele.program.tumbledryer.cottons-auto-load-control = Coton
miele.program.tumbledryer.minimum-iron-auto-load-control = Synthétique
miele.program.washingmachine.cottons = Coton
miele.program.washingmachine.minimum-iron = Synthétique
miele.program.washingmachine.delicates = Fin
miele.program.washingmachine.woollens = Laine
miele.program.washingmachine.silks = Soie
miele.program.washingmachine.starch = Amidonnage
miele.program.washingmachine.rinse = Rinçage seul
miele.program.washingmachine.drain-spin = Vidange/Essorage
miele.program.washingmachine.curtains = Voilages
miele.program.washingmachine.shirts = Chemises
miele.program.washingmachine.denim = Jeans
miele.program.washingmachine.proofing = Imperméabilisation
miele.program.washingmachine.sportswear = Textile sport
miele.program.washingmachine.automatic-plus = Automatic plus
miele.program.washingmachine.outerwear = Textile moderne
miele.program.washingmachine.pillows = Oreillers
miele.program.washingmachine.dark-garments = Textile foncé
miele.program.washingmachine.first-wash = Vêtements neufs
miele.program.washingmachine.steam-care = Finish vapeur
miele.program.washingmachine.freshen-up = Rafraîchir
miele.program.washingmachine.maintenance-wash = Nettoyer machine
miele.program.washingmachine.down-duvets = Couettes plumes
miele.program.washingmachine.express-20 = Express 20
miele.program.washingmachine.down-filled-items = Textile matelassé
miele.program.washingmachine.cottons-eco = Coton éco
miele.program.washingmachine.quickpowerwash = QuickPowerWash
miele.program.washingmachine.mix = Mix textiles
# miele phases
miele.phase.dishwasher.pre-wash = Prélavage
miele.phase.dishwasher.main-wash = Lavage
miele.phase.dishwasher.rinses = Rinçage
miele.phase.dishwasher.final-rinse = Rinçage final
miele.phase.dishwasher.drying = Séchage
miele.phase.dishwasher.finished = Arrêt
miele.phase.oven.heating = Phase de chauffage
miele.phase.oven.temp-hold = Opération en cours
miele.phase.oven.door-open = Porte ouverte
miele.phase.oven.pyrolysis = Pyrolyse
miele.phase.oven.lighting = Eclairage
miele.phase.oven.searing-phase = Phase de saisie
miele.phase.oven.defrost = Décongeler
miele.phase.oven.cooling-down = Refroidissement
miele.phase.oven.energy-save-phase = Eco énergie
miele.phase.tumbledryer.programme-running = Déroulement du programme
miele.phase.tumbledryer.drying = Séchage
miele.phase.tumbledryer.drying-machine-iron = Repasseuse
miele.phase.tumbledryer.drying-hand-iron = Fer à repasser
miele.phase.tumbledryer.drying-normal = Séchage normal
miele.phase.tumbledryer.drying-normal-plus = Séchage normal+
miele.phase.tumbledryer.cooling-down = Refroidissement
miele.phase.tumbledryer.finished = Arrêt
miele.phase.washingmachine.pre-wash = Prélavage
miele.phase.washingmachine.washing = Lavage
miele.phase.washingmachine.rinses = Rinçage
miele.phase.washingmachine.clean = Nettoyage
miele.phase.washingmachine.drain = Pompage
miele.phase.washingmachine.spin = Essorage
miele.phase.washingmachine.anti-crease = Infroissable
miele.phase.washingmachine.finished = Arrêt

View File

@@ -0,0 +1,125 @@
# miele states
miele.state.off = Uit
miele.state.stand-by = Klaar
miele.state.programmed = Programma geselecteerd
#miele.state.waiting-to-start =
miele.state.running = In gebruik
miele.state.paused = Pauze
miele.state.end = Einde
#miele.state.failure =
miele.state.abort = Annulering
#miele.state.idle =
#miele.state.rinse-hold =
#miele.state.service =
#miele.state.super-freezing =
miele.state.super-cooling = Superkoelen
#miele.state.super-heating =
#miele.state.default =
#miele.state.locked =
#miele.state.not-connected =
# miele programs
miele.program.dishwasher.intensive = Intensief
miele.program.dishwasher.maintenance-programme = Machinereiniging
miele.program.dishwasher.eco = ECO
miele.program.dishwasher.normal = Normaal
miele.program.dishwasher.automatic = Automatic
miele.program.dishwasher.solarsave = Solar Spaar
miele.program.dishwasher.gentle = Speciaal
miele.program.dishwasher.extra-quiet = Extra stil
miele.program.dishwasher.hygiene = Hygiëne
miele.program.dishwasher.quickpowerwash = QuickPowerWash
miele.program.dishwasher.tall-items = Zonder bovenrek
miele.program.tumbledryer.automatic-plus = Automatic extra
miele.program.tumbledryer.cottons = Katoen
miele.program.tumbledryer.cottons-hygiene = Katoen Hygiëne
miele.program.tumbledryer.minimum-iron = Kreukherstellend
miele.program.tumbledryer.gentle-minimum-iron = Kreukherstellend
miele.program.tumbledryer.woollens-handcare = Wol
miele.program.tumbledryer.delicates = Fijne was
miele.program.tumbledryer.warm-air = Warme lucht
miele.program.tumbledryer.cool-air = Koude lucht
miele.program.tumbledryer.express = Express
miele.program.tumbledryer.cottons-eco = Katoen Eco
miele.program.tumbledryer.gentle-smoothing = Gladstrijken
miele.program.tumbledryer.proofing = Impregneren
miele.program.tumbledryer.denim = Jeans
miele.program.tumbledryer.gentle-denim = Jeans
miele.program.tumbledryer.shirts = Overhemden
miele.program.tumbledryer.gentle-shirts = Overhemden
miele.program.tumbledryer.sportswear = Sportkleding
miele.program.tumbledryer.outerwear = Outdoor
miele.program.tumbledryer.silks-handcare = Zijde
miele.program.tumbledryer.standard-pillows = Hoofdkussens
miele.program.tumbledryer.basket-programme = Mand witte/bonte was
miele.program.tumbledryer.smoothing = Gladstomen
miele.program.tumbledryer.cottons-auto-load-control = Katoen
miele.program.tumbledryer.minimum-iron-auto-load-control = Kreukherstellend
miele.program.washingmachine.cottons = Witte/Bonte was
miele.program.washingmachine.minimum-iron = Kreukherstellend
miele.program.washingmachine.delicates = Fijne was
miele.program.washingmachine.woollens = Wol
miele.program.washingmachine.silks = Zijde
miele.program.washingmachine.starch = Stijven
miele.program.washingmachine.rinse = Extra spoelen
miele.program.washingmachine.drain-spin = Pompen/Centrifugeren
miele.program.washingmachine.curtains = Vitrage
miele.program.washingmachine.shirts = Overhemden
miele.program.washingmachine.denim = Jeans
miele.program.washingmachine.proofing = Impregneren
miele.program.washingmachine.sportswear = Sportkleding
miele.program.washingmachine.automatic-plus = Automatic exrta
miele.program.washingmachine.outerwear = Outdoor
miele.program.washingmachine.pillows = Hoofdkussens
miele.program.washingmachine.dark-garments = Donker wasgoed
miele.program.washingmachine.first-wash = Nieuw textiel
miele.program.washingmachine.steam-care = Stomen
miele.program.washingmachine.freshen-up = Opfrissen
miele.program.washingmachine.maintenance-wash = Apparaat reinigen
miele.program.washingmachine.down-duvets = Dekbedden
miele.program.washingmachine.express-20 = Express 20
miele.program.washingmachine.down-filled-items = Dons
miele.program.washingmachine.cottons-eco = Witte/Bonte was Eco
miele.program.washingmachine.quickpowerwash = QuickPowerWash
miele.program.washingmachine.mix = Artikelenmix
# miele phases
miele.phase.dishwasher.pre-wash = Voorspoelen
miele.phase.dishwasher.main-wash = Reinigen
miele.phase.dishwasher.rinses = Spoelen
miele.phase.dishwasher.final-rinse = Naspoelen
miele.phase.dishwasher.drying = Drogen
miele.phase.dishwasher.finished = Einde
miele.phase.oven.heating = Opwarmfase
miele.phase.oven.temp-hold = Functie actief
miele.phase.oven.door-open = Deur open
miele.phase.oven.pyrolysis = Pyrolyse
miele.phase.oven.lighting = Verlichting
miele.phase.oven.searing-phase = Aanbraadfase
miele.phase.oven.defrost = Ontdooien
miele.phase.oven.cooling-down = Afkoelen
miele.phase.oven.energy-save-phase = Energiebesparende
miele.phase.tumbledryer.programme-running = Programma wordt uitgevoerd
miele.phase.tumbledryer.drying = Drogen
miele.phase.tumbledryer.drying-machine-iron = Mangeldroog
miele.phase.tumbledryer.drying-hand-iron = Strijkdroog
miele.phase.tumbledryer.drying-normal = Kastdroog
miele.phase.tumbledryer.drying-normal-plus = Kastdroog+
miele.phase.tumbledryer.cooling-down = Afkoelen
miele.phase.tumbledryer.finished = Einde
miele.phase.washingmachine.pre-wash = Voorwas
miele.phase.washingmachine.washing = Wassen
miele.phase.washingmachine.rinses = Spoelen
miele.phase.washingmachine.clean = Reinigen
miele.phase.washingmachine.drain = Pompen
miele.phase.washingmachine.spin = Centrifugeren
miele.phase.washingmachine.anti-crease = Kreukbeveiliging
miele.phase.washingmachine.finished = Einde

View File

@@ -29,7 +29,7 @@
<channel id="switch" typeId="switch"/> <channel id="switch" typeId="switch"/>
<channel id="target" typeId="targetTemperature"> <channel id="target" typeId="targetTemperature">
<label>Temperature</label> <label>Temperature</label>
<description>Temperature of the selected program</description> <description>Temperature of the selected program (10 °C = cold)</description>
</channel> </channel>
<channel id="spinningspeed" typeId="spinningspeed"/> <channel id="spinningspeed" typeId="spinningspeed"/>
<channel id="powerConsumption" typeId="powerConsumption"/> <channel id="powerConsumption" typeId="powerConsumption"/>

View File

@@ -38,6 +38,10 @@
<label>Password</label> <label>Password</label>
<description>Password for the registered Miele@home user.</description> <description>Password for the registered Miele@home user.</description>
</parameter> </parameter>
<parameter name="language" type="text" required="false">
<label>Language</label>
<description>Language for state, program and phase texts. Leave blank for system language.</description>
</parameter>
</config-description> </config-description>
</bridge-type> </bridge-type>

View File

@@ -13,6 +13,8 @@
package org.openhab.binding.miele.internal; package org.openhab.binding.miele.internal;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.openhab.core.library.types.QuantityType; import org.openhab.core.library.types.QuantityType;
@@ -58,6 +60,11 @@ public class DeviceUtilTest extends JavaTest {
assertEquals(UnDefType.UNDEF, DeviceUtil.getTemperatureState("32768")); assertEquals(UnDefType.UNDEF, DeviceUtil.getTemperatureState("32768"));
} }
@Test
public void getTemperatureStateColdValueReturns10Degrees() throws NumberFormatException {
assertEquals(new QuantityType<>(10, SIUnits.CELSIUS), DeviceUtil.getTemperatureState("-32760"));
}
@Test @Test
public void getTemperatureStateNonNumericValueThrowsNumberFormatException() { public void getTemperatureStateNonNumericValueThrowsNumberFormatException() {
assertThrows(NumberFormatException.class, () -> DeviceUtil.getTemperatureState("A")); assertThrows(NumberFormatException.class, () -> DeviceUtil.getTemperatureState("A"));
@@ -67,4 +74,28 @@ public class DeviceUtilTest extends JavaTest {
public void getTemperatureStateNullValueThrowsNumberFormatException() { public void getTemperatureStateNullValueThrowsNumberFormatException() {
assertThrows(NumberFormatException.class, () -> DeviceUtil.getTemperatureState(null)); assertThrows(NumberFormatException.class, () -> DeviceUtil.getTemperatureState(null));
} }
@Test
public void getStateTextStateProviderHasPrecedence() {
assertEquals("I brug", this.getStateTextState("5", "Running", "miele.state.running", "I brug"));
}
@Test
public void getStateTextStateGatewayTextIsReturnedWhenKeyIsUnknown() {
assertEquals("Running", this.getStateTextState("-1", "Running", "key.unknown", "I brug"));
}
@Test
public void getStateTextStateKeyIsReturnedWhenUnknownByGatewayAndProvider() {
assertEquals("state.99", this.getStateTextState("99", null, "key.unknown", "I brug"));
}
private String getStateTextState(String value, String localizedValue, String mockedKey, String mockedValue) {
var metaData = new DeviceMetaData();
metaData.LocalizedValue = localizedValue;
var translationProvider = mock(MieleTranslationProvider.class);
when(translationProvider.getText(mockedKey, metaData.LocalizedValue)).thenReturn(mockedValue);
return DeviceUtil.getStateTextState(value, metaData, translationProvider).toString();
}
} }