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