]> git.basschouten.com Git - openhab-addons.git/blob
4383233f091e85bc0a68a43da6b463f4074b0112
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2022 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.wemo.internal.handler;
14
15 import java.math.BigDecimal;
16 import java.math.RoundingMode;
17 import java.time.Instant;
18 import java.time.ZonedDateTime;
19 import java.util.Map;
20 import java.util.TimeZone;
21 import java.util.concurrent.ConcurrentHashMap;
22
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.eclipse.jdt.annotation.Nullable;
25 import org.openhab.binding.wemo.internal.WemoBindingConstants;
26 import org.openhab.binding.wemo.internal.http.WemoHttpCall;
27 import org.openhab.core.io.transport.upnp.UpnpIOService;
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.QuantityType;
32 import org.openhab.core.library.unit.Units;
33 import org.openhab.core.thing.Thing;
34 import org.openhab.core.thing.ThingStatus;
35 import org.openhab.core.types.State;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39 /**
40  * The {@link WemoInsightHandler} is responsible for handling commands for
41  * a WeMo Insight Switch.
42  *
43  * @author Jacob Laursen - Initial contribution
44  */
45 @NonNullByDefault
46 public class WemoInsightHandler extends WemoHandler {
47
48     private final Logger logger = LoggerFactory.getLogger(WemoInsightHandler.class);
49     private final Map<String, String> stateMap = new ConcurrentHashMap<String, String>();
50
51     public WemoInsightHandler(Thing thing, UpnpIOService upnpIOService, WemoHttpCall wemoHttpCaller) {
52         super(thing, upnpIOService, wemoHttpCaller);
53     }
54
55     @Override
56     public void onValueReceived(@Nullable String variable, @Nullable String value, @Nullable String service) {
57         logger.debug("Received pair '{}':'{}' (service '{}') for thing '{}'",
58                 new Object[] { variable, value, service, this.getThing().getUID() });
59
60         updateStatus(ThingStatus.ONLINE);
61
62         if (!"BinaryState".equals(variable) && !"InsightParams".equals(variable)) {
63             return;
64         }
65
66         if (variable != null && value != null) {
67             this.stateMap.put(variable, value);
68         }
69
70         if (value != null && value.length() > 1) {
71             String insightParams = stateMap.get(variable);
72
73             if (insightParams != null) {
74                 String[] splitInsightParams = insightParams.split("\\|");
75
76                 if (splitInsightParams[0] != null) {
77                     OnOffType binaryState = "0".equals(splitInsightParams[0]) ? OnOffType.OFF : OnOffType.ON;
78                     logger.trace("New InsightParam binaryState '{}' for device '{}' received", binaryState,
79                             getThing().getUID());
80                     updateState(WemoBindingConstants.CHANNEL_STATE, binaryState);
81                 }
82
83                 long lastChangedAt = 0;
84                 try {
85                     lastChangedAt = Long.parseLong(splitInsightParams[1]) * 1000; // convert s to ms
86                 } catch (NumberFormatException e) {
87                     logger.error("Unable to parse lastChangedAt value '{}' for device '{}'; expected long",
88                             splitInsightParams[1], getThing().getUID());
89                 }
90                 ZonedDateTime zoned = ZonedDateTime.ofInstant(Instant.ofEpochMilli(lastChangedAt),
91                         TimeZone.getDefault().toZoneId());
92
93                 State lastChangedAtState = new DateTimeType(zoned);
94                 if (lastChangedAt != 0) {
95                     logger.trace("New InsightParam lastChangedAt '{}' for device '{}' received", lastChangedAtState,
96                             getThing().getUID());
97                     updateState(WemoBindingConstants.CHANNEL_LASTCHANGEDAT, lastChangedAtState);
98                 }
99
100                 State lastOnFor = DecimalType.valueOf(splitInsightParams[2]);
101                 logger.trace("New InsightParam lastOnFor '{}' for device '{}' received", lastOnFor,
102                         getThing().getUID());
103                 updateState(WemoBindingConstants.CHANNEL_LASTONFOR, lastOnFor);
104
105                 State onToday = DecimalType.valueOf(splitInsightParams[3]);
106                 logger.trace("New InsightParam onToday '{}' for device '{}' received", onToday, getThing().getUID());
107                 updateState(WemoBindingConstants.CHANNEL_ONTODAY, onToday);
108
109                 State onTotal = DecimalType.valueOf(splitInsightParams[4]);
110                 logger.trace("New InsightParam onTotal '{}' for device '{}' received", onTotal, getThing().getUID());
111                 updateState(WemoBindingConstants.CHANNEL_ONTOTAL, onTotal);
112
113                 State timespan = DecimalType.valueOf(splitInsightParams[5]);
114                 logger.trace("New InsightParam timespan '{}' for device '{}' received", timespan, getThing().getUID());
115                 updateState(WemoBindingConstants.CHANNEL_TIMESPAN, timespan);
116
117                 State averagePower = new QuantityType<>(DecimalType.valueOf(splitInsightParams[6]), Units.WATT); // natively
118                                                                                                                  // given
119                                                                                                                  // in W
120                 logger.trace("New InsightParam averagePower '{}' for device '{}' received", averagePower,
121                         getThing().getUID());
122                 updateState(WemoBindingConstants.CHANNEL_AVERAGEPOWER, averagePower);
123
124                 BigDecimal currentMW = new BigDecimal(splitInsightParams[7]);
125                 State currentPower = new QuantityType<>(currentMW.divide(new BigDecimal(1000), 0, RoundingMode.HALF_UP),
126                         Units.WATT); // recalculate
127                 // mW to W
128                 logger.trace("New InsightParam currentPower '{}' for device '{}' received", currentPower,
129                         getThing().getUID());
130                 updateState(WemoBindingConstants.CHANNEL_CURRENTPOWER, currentPower);
131
132                 BigDecimal energyTodayMWMin = new BigDecimal(splitInsightParams[8]);
133                 // recalculate mW-mins to Wh
134                 State energyToday = new QuantityType<>(
135                         energyTodayMWMin.divide(new BigDecimal(60000), 0, RoundingMode.HALF_UP), Units.WATT_HOUR);
136                 logger.trace("New InsightParam energyToday '{}' for device '{}' received", energyToday,
137                         getThing().getUID());
138                 updateState(WemoBindingConstants.CHANNEL_ENERGYTODAY, energyToday);
139
140                 BigDecimal energyTotalMWMin = new BigDecimal(splitInsightParams[9]);
141                 // recalculate mW-mins to Wh
142                 State energyTotal = new QuantityType<>(
143                         energyTotalMWMin.divide(new BigDecimal(60000), 0, RoundingMode.HALF_UP), Units.WATT_HOUR);
144                 logger.trace("New InsightParam energyTotal '{}' for device '{}' received", energyTotal,
145                         getThing().getUID());
146                 updateState(WemoBindingConstants.CHANNEL_ENERGYTOTAL, energyTotal);
147
148                 if (splitInsightParams.length > 10 && splitInsightParams[10] != null) {
149                     BigDecimal standByLimitMW = new BigDecimal(splitInsightParams[10]);
150                     State standByLimit = new QuantityType<>(
151                             standByLimitMW.divide(new BigDecimal(1000), 0, RoundingMode.HALF_UP), Units.WATT); // recalculate
152                     // mW to W
153                     logger.trace("New InsightParam standByLimit '{}' for device '{}' received", standByLimit,
154                             getThing().getUID());
155                     updateState(WemoBindingConstants.CHANNEL_STANDBYLIMIT, standByLimit);
156
157                     if (currentMW.divide(new BigDecimal(1000), 0, RoundingMode.HALF_UP).intValue() > standByLimitMW
158                             .divide(new BigDecimal(1000), 0, RoundingMode.HALF_UP).intValue()) {
159                         updateState(WemoBindingConstants.CHANNEL_ONSTANDBY, OnOffType.OFF);
160                     } else {
161                         updateState(WemoBindingConstants.CHANNEL_ONSTANDBY, OnOffType.ON);
162                     }
163                 }
164             }
165         }
166     }
167 }