]> git.basschouten.com Git - openhab-addons.git/blob
24aa871e6b1247879d5342bc0111585947d9c715
[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.verisure.internal.handler;
14
15 import static org.openhab.binding.verisure.internal.VerisureBindingConstants.*;
16
17 import java.math.BigDecimal;
18 import java.util.ArrayList;
19 import java.util.List;
20 import java.util.Set;
21
22 import org.eclipse.jdt.annotation.NonNullByDefault;
23 import org.eclipse.jdt.annotation.Nullable;
24 import org.eclipse.jetty.http.HttpStatus;
25 import org.openhab.binding.verisure.internal.VerisureSession;
26 import org.openhab.binding.verisure.internal.dto.VerisureSmartPlugsDTO;
27 import org.openhab.binding.verisure.internal.dto.VerisureSmartPlugsDTO.Smartplug;
28 import org.openhab.core.library.types.OnOffType;
29 import org.openhab.core.library.types.StringType;
30 import org.openhab.core.thing.Channel;
31 import org.openhab.core.thing.ChannelUID;
32 import org.openhab.core.thing.Thing;
33 import org.openhab.core.thing.ThingStatus;
34 import org.openhab.core.thing.ThingTypeUID;
35 import org.openhab.core.types.Command;
36 import org.openhab.core.types.RefreshType;
37 import org.openhab.core.types.State;
38 import org.openhab.core.types.UnDefType;
39
40 /**
41  * Handler for the Smart Plug Device thing type that Verisure provides.
42  *
43  * @author Jan Gustafsson - Initial contribution
44  *
45  */
46 @NonNullByDefault
47 public class VerisureSmartPlugThingHandler extends VerisureThingHandler<VerisureSmartPlugsDTO> {
48
49     public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Set.of(THING_TYPE_SMARTPLUG);
50
51     private static final int REFRESH_DELAY_SECONDS = 10;
52
53     public VerisureSmartPlugThingHandler(Thing thing) {
54         super(thing);
55     }
56
57     @Override
58     public void handleCommand(ChannelUID channelUID, Command command) {
59         logger.debug("handleCommand, channel: {}, command: {}", channelUID, command);
60         if (command instanceof RefreshType) {
61             super.handleCommand(channelUID, command);
62         } else if (channelUID.getId().equals(CHANNEL_SMARTPLUG_STATUS)) {
63             handleSmartPlugState(command);
64             scheduleImmediateRefresh(REFRESH_DELAY_SECONDS);
65         } else {
66             logger.warn("Unknown command! {}", command);
67         }
68     }
69
70     private void handleSmartPlugState(Command command) {
71         String deviceId = config.getDeviceId();
72         VerisureSession session = getSession();
73         if (session != null) {
74             VerisureSmartPlugsDTO smartPlug = session.getVerisureThing(deviceId, getVerisureThingClass());
75             if (smartPlug != null) {
76                 BigDecimal installationId = smartPlug.getSiteId();
77                 String url = START_GRAPHQL;
78                 String operation;
79                 boolean isOperation;
80                 if (command == OnOffType.OFF) {
81                     operation = "false";
82                     isOperation = false;
83                 } else if (command == OnOffType.ON) {
84                     operation = "true";
85                     isOperation = true;
86                 } else {
87                     logger.debug("Unknown command! {}", command);
88                     return;
89                 }
90                 String query = "mutation UpdateState($giid: String!, $deviceLabel: String!, $state: Boolean!) {\n SmartPlugSetState(giid: $giid, input: [{deviceLabel: $deviceLabel, state: $state}])\n}\n";
91                 ArrayList<SmartPlugDTO> list = new ArrayList<>();
92                 SmartPlugDTO smartPlugJSON = new SmartPlugDTO();
93                 VariablesDTO variables = new VariablesDTO();
94
95                 variables.setDeviceLabel(deviceId);
96                 variables.setGiid(installationId.toString());
97                 variables.setState(isOperation);
98                 smartPlugJSON.setOperationName("UpdateState");
99                 smartPlugJSON.setVariables(variables);
100                 smartPlugJSON.setQuery(query);
101                 list.add(smartPlugJSON);
102
103                 String queryQLSmartPlugSetState = gson.toJson(list);
104                 logger.debug("Trying to set SmartPlug state to {} with URL {} and data {}", operation, url,
105                         queryQLSmartPlugSetState);
106                 int httpResultCode = session.sendCommand(url, queryQLSmartPlugSetState, installationId);
107                 if (httpResultCode == HttpStatus.OK_200) {
108                     logger.debug("Smartplug state successfully changed!");
109                 } else {
110                     logger.warn("Failed to send command, HTTP result code {}", httpResultCode);
111                 }
112             }
113         }
114     }
115
116     @Override
117     public Class<VerisureSmartPlugsDTO> getVerisureThingClass() {
118         return VerisureSmartPlugsDTO.class;
119     }
120
121     @Override
122     public synchronized void update(VerisureSmartPlugsDTO thing) {
123         updateSmartPlugState(thing);
124         updateStatus(ThingStatus.ONLINE);
125     }
126
127     private void updateSmartPlugState(VerisureSmartPlugsDTO smartPlugJSON) {
128         List<Smartplug> smartPlugList = smartPlugJSON.getData().getInstallation().getSmartplugs();
129         if (!smartPlugList.isEmpty()) {
130             Smartplug smartplug = smartPlugList.get(0);
131             String smartPlugStatus = smartplug.getCurrentState();
132             if (smartPlugStatus != null) {
133                 getThing().getChannels().stream().map(Channel::getUID)
134                         .filter(channelUID -> isLinked(channelUID) && !"timestamp".equals(channelUID.getId()))
135                         .forEach(channelUID -> {
136                             State state = getValue(channelUID.getId(), smartplug, smartPlugStatus);
137                             updateState(channelUID, state);
138                         });
139                 updateInstallationChannels(smartPlugJSON);
140             }
141         } else {
142             logger.debug("SmartPlugList is empty!");
143         }
144     }
145
146     public State getValue(String channelId, Smartplug smartplug, String smartPlugStatus) {
147         switch (channelId) {
148             case CHANNEL_SMARTPLUG_STATUS:
149                 if ("ON".equals(smartPlugStatus)) {
150                     return OnOffType.ON;
151                 } else if ("OFF".equals(smartPlugStatus)) {
152                     return OnOffType.OFF;
153                 } else if ("PENDING".equals(smartPlugStatus)) {
154                     // Schedule another refresh.
155                     logger.debug("Issuing another immediate refresh since status is still PENDING ...");
156                     this.scheduleImmediateRefresh(REFRESH_DELAY_SECONDS);
157                 }
158                 break;
159             case CHANNEL_LOCATION:
160                 String location = smartplug.getDevice().getArea();
161                 return location != null ? new StringType(location) : UnDefType.NULL;
162             case CHANNEL_HAZARDOUS:
163                 return OnOffType.from(smartplug.isHazardous());
164         }
165         return UnDefType.UNDEF;
166     }
167
168     private static class SmartPlugDTO {
169
170         @SuppressWarnings("unused")
171         private @Nullable String operationName;
172         @SuppressWarnings("unused")
173         private VariablesDTO variables = new VariablesDTO();
174         @SuppressWarnings("unused")
175         private @Nullable String query;
176
177         public void setOperationName(String operationName) {
178             this.operationName = operationName;
179         }
180
181         public void setVariables(VariablesDTO variables) {
182             this.variables = variables;
183         }
184
185         public void setQuery(String query) {
186             this.query = query;
187         }
188     }
189
190     private static class VariablesDTO {
191
192         @SuppressWarnings("unused")
193         private @Nullable String giid;
194         @SuppressWarnings("unused")
195         private @Nullable String deviceLabel;
196         @SuppressWarnings("unused")
197         private boolean state;
198
199         public void setGiid(String giid) {
200             this.giid = giid;
201         }
202
203         public void setDeviceLabel(String deviceLabel) {
204             this.deviceLabel = deviceLabel;
205         }
206
207         public void setState(boolean state) {
208             this.state = state;
209         }
210     }
211
212     @Override
213     public void updateTriggerChannel(String event) {
214         logger.debug("SmartPlugThingHandler trigger event {}", event);
215         triggerChannel(CHANNEL_SMARTPLUG_TRIGGER_CHANNEL, event);
216     }
217 }