]> git.basschouten.com Git - openhab-addons.git/blob
b3addc8701556f9fc53efce6e19d03a496c0bb99
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 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 org.openhab.binding.miele.internal.MieleBindingConstants.MIELE_DEVICE_CLASS_DISHWASHER;
16 import static org.openhab.binding.miele.internal.MieleBindingConstants.POWER_CONSUMPTION_CHANNEL_ID;
17 import static org.openhab.binding.miele.internal.MieleBindingConstants.WATER_CONSUMPTION_CHANNEL_ID;
18
19 import java.math.BigDecimal;
20
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.openhab.binding.miele.internal.api.dto.DeviceProperty;
23 import org.openhab.binding.miele.internal.exceptions.MieleRpcException;
24 import org.openhab.core.i18n.LocaleProvider;
25 import org.openhab.core.i18n.TimeZoneProvider;
26 import org.openhab.core.i18n.TranslationProvider;
27 import org.openhab.core.library.types.OnOffType;
28 import org.openhab.core.library.types.QuantityType;
29 import org.openhab.core.library.unit.Units;
30 import org.openhab.core.thing.ChannelUID;
31 import org.openhab.core.thing.Thing;
32 import org.openhab.core.types.Command;
33 import org.openhab.core.types.RefreshType;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36
37 import com.google.gson.JsonElement;
38
39 /**
40  * The {@link DishwasherHandler} is responsible for handling commands,
41  * which are sent to one of the channels
42  *
43  * @author Karel Goderis - Initial contribution
44  * @author Kai Kreuzer - fixed handling of REFRESH commands
45  * @author Martin Lepsy - fixed handling of empty JSON results
46  * @author Jacob Laursen - Fixed multicast and protocol support (ZigBee/LAN), added power/water consumption channels
47  */
48 @NonNullByDefault
49 public class DishwasherHandler extends MieleApplianceHandler<DishwasherChannelSelector>
50         implements ExtendedDeviceStateListener {
51
52     private static final int POWER_CONSUMPTION_BYTE_POSITION = 16;
53     private static final int WATER_CONSUMPTION_BYTE_POSITION = 18;
54     private static final int EXTENDED_STATE_MIN_SIZE_BYTES = 19;
55
56     private final Logger logger = LoggerFactory.getLogger(DishwasherHandler.class);
57
58     public DishwasherHandler(Thing thing, TranslationProvider i18nProvider, LocaleProvider localeProvider,
59             TimeZoneProvider timeZoneProvider) {
60         super(thing, i18nProvider, localeProvider, timeZoneProvider, DishwasherChannelSelector.class,
61                 MIELE_DEVICE_CLASS_DISHWASHER);
62     }
63
64     @Override
65     public void handleCommand(ChannelUID channelUID, Command command) {
66         super.handleCommand(channelUID, command);
67
68         String channelID = channelUID.getId();
69         String applianceId = this.applianceId;
70         if (applianceId == null) {
71             logger.warn("Command '{}' failed, appliance id is unknown", command);
72             return;
73         }
74
75         DishwasherChannelSelector selector = (DishwasherChannelSelector) getValueSelectorFromChannelID(channelID);
76         JsonElement result = null;
77
78         try {
79             switch (selector) {
80                 case SWITCH: {
81                     MieleBridgeHandler bridgeHandler = getMieleBridgeHandler();
82                     if (bridgeHandler == null) {
83                         logger.warn("Command '{}' failed, missing bridge handler", command);
84                         return;
85                     }
86                     if (command.equals(OnOffType.ON)) {
87                         result = bridgeHandler.invokeOperation(applianceId, modelID, "start");
88                     } else if (command.equals(OnOffType.OFF)) {
89                         result = bridgeHandler.invokeOperation(applianceId, modelID, "stop");
90                     }
91                     break;
92                 }
93                 default: {
94                     if (!(command instanceof RefreshType)) {
95                         logger.debug("{} is a read-only channel that does not accept commands",
96                                 selector.getChannelID());
97                     }
98                 }
99             }
100             // process result
101             if (result != null && isResultProcessable(result)) {
102                 logger.debug("Result of operation is {}", result.getAsString());
103             }
104         } catch (IllegalArgumentException e) {
105             logger.warn(
106                     "An error occurred while trying to set the read-only variable associated with channel '{}' to '{}'",
107                     channelID, command.toString());
108         } catch (MieleRpcException e) {
109             Throwable cause = e.getCause();
110             if (cause == null) {
111                 logger.warn("An error occurred while trying to invoke operation: {}", e.getMessage());
112             } else {
113                 logger.warn("An error occurred while trying to invoke operation: {} -> {}", e.getMessage(),
114                         cause.getMessage());
115             }
116         }
117     }
118
119     @Override
120     public void onAppliancePropertyChanged(DeviceProperty dp) {
121         super.onAppliancePropertyChanged(dp);
122         updateSwitchStartStopFromState(dp);
123     }
124
125     @Override
126     public void onApplianceExtendedStateChanged(byte[] extendedDeviceState) {
127         if (extendedDeviceState.length < EXTENDED_STATE_MIN_SIZE_BYTES) {
128             logger.debug("Insufficient extended state data to extract consumption values: {}", extendedDeviceState);
129             return;
130         }
131
132         BigDecimal kiloWattHoursTenths = BigDecimal
133                 .valueOf(extendedDeviceState[POWER_CONSUMPTION_BYTE_POSITION] & 0xff);
134         var kiloWattHours = new QuantityType<>(kiloWattHoursTenths.divide(BigDecimal.valueOf(10)), Units.KILOWATT_HOUR);
135         updateExtendedState(POWER_CONSUMPTION_CHANNEL_ID, kiloWattHours);
136
137         BigDecimal decilitres = BigDecimal.valueOf(extendedDeviceState[WATER_CONSUMPTION_BYTE_POSITION] & 0xff);
138         var litres = new QuantityType<>(decilitres.divide(BigDecimal.valueOf(10)), Units.LITRE);
139         updateExtendedState(WATER_CONSUMPTION_CHANNEL_ID, litres);
140     }
141 }