]> git.basschouten.com Git - openhab-addons.git/blob
4fad63fe5dc293c4f3581a37b0b71b57a59fbd46
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2021 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.miele.internal.handler;
14
15 import static java.util.Map.entry;
16 import static org.openhab.binding.miele.internal.MieleBindingConstants.*;
17
18 import java.lang.reflect.Method;
19 import java.text.SimpleDateFormat;
20 import java.util.Date;
21 import java.util.Map;
22 import java.util.Map.Entry;
23 import java.util.TimeZone;
24
25 import org.openhab.binding.miele.internal.DeviceUtil;
26 import org.openhab.binding.miele.internal.handler.MieleBridgeHandler.DeviceMetaData;
27 import org.openhab.core.library.types.DateTimeType;
28 import org.openhab.core.library.types.DecimalType;
29 import org.openhab.core.library.types.OnOffType;
30 import org.openhab.core.library.types.OpenClosedType;
31 import org.openhab.core.library.types.QuantityType;
32 import org.openhab.core.library.types.StringType;
33 import org.openhab.core.types.State;
34 import org.openhab.core.types.Type;
35 import org.openhab.core.types.UnDefType;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39 import com.google.gson.JsonElement;
40
41 /**
42  * The {@link ApplianceChannelSelector} for washing machines
43  *
44  * @author Karel Goderis - Initial contribution
45  * @author Kai Kreuzer - Changed START_TIME to DateTimeType
46  * @author Jacob Laursen - Added power/water consumption channels, UoM for temperatures, raw channels
47  */
48 public enum WashingMachineChannelSelector implements ApplianceChannelSelector {
49
50     PRODUCT_TYPE("productTypeId", "productType", StringType.class, true, false),
51     DEVICE_TYPE("mieleDeviceType", "deviceType", StringType.class, true, false),
52     STATE_TEXT(STATE_PROPERTY_NAME, STATE_TEXT_CHANNEL_ID, StringType.class, false, false),
53     STATE(null, STATE_CHANNEL_ID, DecimalType.class, false, false),
54     PROGRAM_TEXT(PROGRAM_ID_PROPERTY_NAME, PROGRAM_TEXT_CHANNEL_ID, StringType.class, false, false) {
55         @Override
56         public State getState(String s, DeviceMetaData dmd) {
57             State state = getTextState(s, dmd, programs, MISSING_PROGRAM_TEXT_PREFIX);
58             if (state != null) {
59                 return state;
60             }
61             return super.getState(s, dmd);
62         }
63     },
64     PROGRAM(null, PROGRAM_CHANNEL_ID, DecimalType.class, false, false),
65     PROGRAMTYPE("programType", "type", StringType.class, false, false),
66     PROGRAM_PHASE_TEXT(PHASE_PROPERTY_NAME, PHASE_TEXT_CHANNEL_ID, StringType.class, false, false) {
67         @Override
68         public State getState(String s, DeviceMetaData dmd) {
69             State state = getTextState(s, dmd, phases, MISSING_PHASE_TEXT_PREFIX);
70             if (state != null) {
71                 return state;
72             }
73             return super.getState(s, dmd);
74         }
75     },
76     PROGRAM_PHASE(RAW_PHASE_PROPERTY_NAME, PHASE_CHANNEL_ID, DecimalType.class, false, false),
77     START_TIME("startTime", "start", DateTimeType.class, false, false) {
78         @Override
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"));
83             try {
84                 date.setTime(Long.valueOf(s) * 60000);
85             } catch (Exception e) {
86                 date.setTime(0);
87             }
88             return getState(dateFormatter.format(date));
89         }
90     },
91     DURATION("duration", "duration", DateTimeType.class, false, false) {
92         @Override
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"));
97             try {
98                 date.setTime(Long.valueOf(s.trim()) * 60000);
99             } catch (Exception e) {
100                 date.setTime(0);
101             }
102             return getState(dateFormatter.format(date));
103         }
104     },
105     ELAPSED_TIME("elapsedTime", "elapsed", DateTimeType.class, false, false) {
106         @Override
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"));
111             try {
112                 date.setTime(Long.valueOf(s) * 60000);
113             } catch (Exception e) {
114                 date.setTime(0);
115             }
116             return getState(dateFormatter.format(date));
117         }
118     },
119     FINISH_TIME("finishTime", "finish", DateTimeType.class, false, false) {
120         @Override
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"));
125             try {
126                 date.setTime(Long.valueOf(s) * 60000);
127             } catch (Exception e) {
128                 date.setTime(0);
129             }
130             return getState(dateFormatter.format(date));
131         }
132     },
133     TARGET_TEMP("targetTemperature", "target", QuantityType.class, false, false) {
134         @Override
135         public State getState(String s, DeviceMetaData dmd) {
136             return getTemperatureState(s);
137         }
138     },
139     SPINNING_SPEED("spinningSpeed", "spinningspeed", StringType.class, false, false) {
140         @Override
141         public State getState(String s, DeviceMetaData dmd) {
142             if ("0".equals(s)) {
143                 return getState("Without spinning");
144             }
145             if ("256".equals(s)) {
146                 return getState("Rinsing");
147             }
148             return getState(Integer.toString((Integer.valueOf(s))));
149         }
150     },
151     DOOR("signalDoor", "door", OpenClosedType.class, false, false) {
152         @Override
153
154         public State getState(String s, DeviceMetaData dmd) {
155             if ("true".equals(s)) {
156                 return getState("OPEN");
157             }
158
159             if ("false".equals(s)) {
160                 return getState("CLOSED");
161             }
162
163             return UnDefType.UNDEF;
164         }
165     },
166     SWITCH(null, "switch", OnOffType.class, false, false),
167     POWER_CONSUMPTION(EXTENDED_DEVICE_STATE_PROPERTY_NAME, POWER_CONSUMPTION_CHANNEL_ID, QuantityType.class, false,
168             true),
169     WATER_CONSUMPTION(EXTENDED_DEVICE_STATE_PROPERTY_NAME, WATER_CONSUMPTION_CHANNEL_ID, QuantityType.class, false,
170             true);
171
172     private final Logger logger = LoggerFactory.getLogger(WashingMachineChannelSelector.class);
173
174     private static final Map<String, String> programs = Map.ofEntries(entry("1", "Cottons"), entry("3", "Minimum iron"),
175             entry("4", "Delicates"), entry("8", "Woollens"), entry("9", "Silks"), entry("17", "Starch"),
176             entry("18", "Rinse"), entry("21", "Drain/Spin"), entry("22", "Curtains"), entry("23", "Shirts"),
177             entry("24", "Denim"), entry("27", "Proofing"), entry("29", "Sportswear"), entry("31", "Automatic Plus"),
178             entry("37", "Outerwear"), entry("39", "Pillows"), entry("50", "Dark Garments"), entry("53", "First wash"),
179             entry("75", "Steam care"), entry("76", "Freshen up"), entry("91", "Maintenance wash"),
180             entry("95", "Down duvets"), entry("122", "Express 20"), entry("129", "Down filled items"),
181             entry("133", "Cottons Eco"), entry("146", "QuickPowerWash"), entry("65532", "Mix"));
182
183     private static final Map<String, String> phases = Map.ofEntries(entry("1", "Pre-wash"), entry("4", "Washing"),
184             entry("5", "Rinses"), entry("7", "Clean"), entry("9", "Drain"), entry("10", "Spin"),
185             entry("11", "Anti-crease"), entry("12", "Finished"));
186
187     private final String mieleID;
188     private final String channelID;
189     private final Class<? extends Type> typeClass;
190     private final boolean isProperty;
191     private final boolean isExtendedState;
192
193     WashingMachineChannelSelector(String propertyID, String channelID, Class<? extends Type> typeClass,
194             boolean isProperty, boolean isExtendedState) {
195         this.mieleID = propertyID;
196         this.channelID = channelID;
197         this.typeClass = typeClass;
198         this.isProperty = isProperty;
199         this.isExtendedState = isExtendedState;
200     }
201
202     @Override
203     public String toString() {
204         return mieleID;
205     }
206
207     @Override
208     public String getMieleID() {
209         return mieleID;
210     }
211
212     @Override
213     public String getChannelID() {
214         return channelID;
215     }
216
217     @Override
218     public boolean isProperty() {
219         return isProperty;
220     }
221
222     @Override
223     public boolean isExtendedState() {
224         return isExtendedState;
225     }
226
227     @Override
228     public State getState(String s, DeviceMetaData dmd) {
229         if (dmd != null) {
230             String localizedValue = getMieleEnum(s, dmd);
231             if (localizedValue == null) {
232                 localizedValue = dmd.LocalizedValue;
233             }
234             if (localizedValue == null) {
235                 localizedValue = s;
236             }
237
238             return getState(localizedValue);
239         } else {
240             return getState(s);
241         }
242     }
243
244     public State getState(String s) {
245         try {
246             Method valueOf = typeClass.getMethod("valueOf", String.class);
247             State state = (State) valueOf.invoke(typeClass, s);
248             if (state != null) {
249                 return state;
250             }
251         } catch (Exception e) {
252             logger.error("An exception occurred while converting '{}' into a State", s);
253         }
254
255         return null;
256     }
257
258     public State getTemperatureState(String s) {
259         try {
260             return DeviceUtil.getTemperatureState(s);
261         } catch (NumberFormatException e) {
262             logger.warn("An exception occurred while converting '{}' into a State", s);
263             return UnDefType.UNDEF;
264         }
265     }
266
267     public State getTextState(String s, DeviceMetaData dmd, Map<String, String> valueMap, String prefix) {
268         if ("0".equals(s)) {
269             return UnDefType.UNDEF;
270         }
271
272         if (dmd == null || dmd.LocalizedValue == null || dmd.LocalizedValue.startsWith(prefix)) {
273             String text = valueMap.get(s);
274             if (text != null) {
275                 return getState(text);
276             }
277             if (dmd == null || dmd.LocalizedValue == null) {
278                 return getState(prefix + s);
279             }
280         }
281
282         return null;
283     }
284
285     public String getMieleEnum(String s, DeviceMetaData dmd) {
286         if (dmd.MieleEnum != null) {
287             for (Entry<String, JsonElement> enumEntry : dmd.MieleEnum.entrySet()) {
288                 if (enumEntry.getValue().getAsString().trim().equals(s.trim())) {
289                     return enumEntry.getKey();
290                 }
291             }
292         }
293
294         return null;
295     }
296 }