2 * Copyright (c) 2010-2021 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.miele.internal.handler;
15 import static java.util.Map.entry;
16 import static org.openhab.binding.miele.internal.MieleBindingConstants.*;
18 import java.lang.reflect.Method;
19 import java.text.SimpleDateFormat;
20 import java.util.Date;
22 import java.util.Map.Entry;
23 import java.util.TimeZone;
25 import org.openhab.binding.miele.internal.handler.MieleBridgeHandler.DeviceMetaData;
26 import org.openhab.core.library.types.DateTimeType;
27 import org.openhab.core.library.types.DecimalType;
28 import org.openhab.core.library.types.OnOffType;
29 import org.openhab.core.library.types.OpenClosedType;
30 import org.openhab.core.library.types.StringType;
31 import org.openhab.core.types.State;
32 import org.openhab.core.types.Type;
33 import org.openhab.core.types.UnDefType;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
37 import com.google.gson.JsonElement;
40 * The {@link ApplianceChannelSelector} for tumble dryers
42 * @author Karel Goderis - Initial contribution
43 * @author Kai Kreuzer - Changed START_TIME to DateTimeType
44 * @author Jacob Laursen - Added raw channels
46 public enum TumbleDryerChannelSelector implements ApplianceChannelSelector {
48 PRODUCT_TYPE("productTypeId", "productType", StringType.class, true),
49 DEVICE_TYPE("mieleDeviceType", "deviceType", StringType.class, true),
50 BRAND_ID("brandId", "brandId", StringType.class, true),
51 COMPANY_ID("companyId", "companyId", StringType.class, true),
52 STATE_TEXT(STATE_PROPERTY_NAME, STATE_TEXT_CHANNEL_ID, StringType.class, false),
53 STATE(null, STATE_CHANNEL_ID, DecimalType.class, false),
54 PROGRAM_TEXT(PROGRAM_ID_PROPERTY_NAME, PROGRAM_TEXT_CHANNEL_ID, StringType.class, false) {
56 public State getState(String s, DeviceMetaData dmd) {
57 State state = getTextState(s, dmd, programs, MISSING_PROGRAM_TEXT_PREFIX);
61 return super.getState(s, dmd);
64 PROGRAM(null, PROGRAM_CHANNEL_ID, DecimalType.class, false),
65 PROGRAMTYPE("programType", "type", StringType.class, false),
66 PROGRAM_PHASE_TEXT(PHASE_PROPERTY_NAME, PHASE_TEXT_CHANNEL_ID, StringType.class, false) {
68 public State getState(String s, DeviceMetaData dmd) {
69 State state = getTextState(s, dmd, phases, MISSING_PHASE_TEXT_PREFIX);
73 return super.getState(s, dmd);
76 PROGRAM_PHASE(RAW_PHASE_PROPERTY_NAME, PHASE_CHANNEL_ID, DecimalType.class, false),
77 START_TIME("startTime", "start", DateTimeType.class, false) {
79 public State getState(String s, DeviceMetaData dmd) {
80 Date date = new Date();
81 SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
82 dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT+0"));
84 date.setTime(Long.valueOf(s) * 60000);
85 } catch (Exception e) {
88 return getState(dateFormatter.format(date));
91 DURATION("duration", "duration", DateTimeType.class, false) {
93 public State getState(String s, DeviceMetaData dmd) {
94 Date date = new Date();
95 SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
96 dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT+0"));
98 date.setTime(Long.valueOf(s) * 60000);
99 } catch (Exception e) {
102 return getState(dateFormatter.format(date));
105 ELAPSED_TIME("elapsedTime", "elapsed", DateTimeType.class, false) {
107 public State getState(String s, DeviceMetaData dmd) {
108 Date date = new Date();
109 SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
110 dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT+0"));
112 date.setTime(Long.valueOf(s) * 60000);
113 } catch (Exception e) {
116 return getState(dateFormatter.format(date));
119 FINISH_TIME("finishTime", "finish", DateTimeType.class, false) {
121 public State getState(String s, DeviceMetaData dmd) {
122 Date date = new Date();
123 SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
124 dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT+0"));
126 date.setTime(Long.valueOf(s) * 60000);
127 } catch (Exception e) {
130 return getState(dateFormatter.format(date));
133 DRYING_STEP("dryingStep", "step", DecimalType.class, false) {
135 public State getState(String s, DeviceMetaData dmd) {
139 DOOR("signalDoor", "door", OpenClosedType.class, false) {
142 public State getState(String s, DeviceMetaData dmd) {
143 if ("true".equals(s)) {
144 return getState("OPEN");
147 if ("false".equals(s)) {
148 return getState("CLOSED");
151 return UnDefType.UNDEF;
154 SWITCH(null, "switch", OnOffType.class, false);
156 private final Logger logger = LoggerFactory.getLogger(TumbleDryerChannelSelector.class);
158 private final static Map<String, String> programs = Map.ofEntries(entry("10", "Automatic Plus"),
159 entry("23", "Cottons hygiene"), entry("30", "Minimum iron"), entry("31", "Gentle minimum iron"),
160 entry("40", "Woollens handcare"), entry("50", "Delicates"), entry("60", "Warm Air"),
161 entry("70", "Cool air"), entry("80", "Express"), entry("90", "Cottons"), entry("100", "Gentle smoothing"),
162 entry("120", "Proofing"), entry("130", "Denim"), entry("131", "Gentle denim"), entry("140", "Shirts"),
163 entry("141", "Gentle shirts"), entry("150", "Sportswear"), entry("160", "Outerwear"),
164 entry("170", "Silks handcare"), entry("190", "Standard pillows"), entry("220", "Basket programme"),
165 entry("240", "Smoothing"), entry("65000", "Cottons, auto load control"),
166 entry("65001", "Minimum iron, auto load control"));
168 private final static Map<String, String> phases = Map.ofEntries(entry("1", "Programme running"),
169 entry("2", "Drying"), entry("3", "Drying Machine iron"), entry("4", "Drying Hand iron"),
170 entry("5", "Drying Normal"), entry("6", "Drying Normal+"), entry("7", "Cooling down"),
171 entry("8", "Drying Hand iron"), entry("10", "Finished"));
173 private final String mieleID;
174 private final String channelID;
175 private final Class<? extends Type> typeClass;
176 private final boolean isProperty;
178 TumbleDryerChannelSelector(String propertyID, String channelID, Class<? extends Type> typeClass,
179 boolean isProperty) {
180 this.mieleID = propertyID;
181 this.channelID = channelID;
182 this.typeClass = typeClass;
183 this.isProperty = isProperty;
187 public String toString() {
192 public String getMieleID() {
197 public String getChannelID() {
202 public boolean isProperty() {
207 public boolean isExtendedState() {
212 public State getState(String s, DeviceMetaData dmd) {
214 String localizedValue = getMieleEnum(s, dmd);
215 if (localizedValue == null) {
216 localizedValue = dmd.LocalizedValue;
218 if (localizedValue == null) {
222 return getState(localizedValue);
228 public State getState(String s) {
230 Method valueOf = typeClass.getMethod("valueOf", String.class);
231 State state = (State) valueOf.invoke(typeClass, s);
235 } catch (Exception e) {
236 logger.error("An exception occurred while converting '{}' into a State", s);
242 public State getTextState(String s, DeviceMetaData dmd, Map<String, String> valueMap, String prefix) {
244 return UnDefType.UNDEF;
247 if (dmd == null || dmd.LocalizedValue == null || dmd.LocalizedValue.startsWith(prefix)) {
248 String text = valueMap.get(s);
250 return getState(text);
252 if (dmd == null || dmd.LocalizedValue == null) {
253 return getState(prefix + s);
260 public String getMieleEnum(String s, DeviceMetaData dmd) {
261 if (dmd.MieleEnum != null) {
262 for (Entry<String, JsonElement> enumEntry : dmd.MieleEnum.entrySet()) {
263 if (enumEntry.getValue().getAsString().trim().equals(s.trim())) {
264 return enumEntry.getKey();