]> git.basschouten.com Git - openhab-addons.git/blob
06f5ec5ded78326826984ea6c5bec5394a0b0ab4
[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.Collections;
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.VerisureAlarmsDTO;
27 import org.openhab.binding.verisure.internal.dto.VerisureAlarmsDTO.ArmState;
28 import org.openhab.core.library.types.StringType;
29 import org.openhab.core.thing.Channel;
30 import org.openhab.core.thing.ChannelUID;
31 import org.openhab.core.thing.Thing;
32 import org.openhab.core.thing.ThingStatus;
33 import org.openhab.core.thing.ThingTypeUID;
34 import org.openhab.core.types.Command;
35 import org.openhab.core.types.RefreshType;
36 import org.openhab.core.types.State;
37 import org.openhab.core.types.UnDefType;
38
39 /**
40  * Handler for the Alarm Device thing type that Verisure provides.
41  *
42  * @author Jan Gustafsson - Initial contribution
43  *
44  */
45 @NonNullByDefault
46 public class VerisureAlarmThingHandler extends VerisureThingHandler<VerisureAlarmsDTO> {
47
48     public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Collections.singleton(THING_TYPE_ALARM);
49
50     private static final int REFRESH_DELAY_SECONDS = 10;
51
52     public VerisureAlarmThingHandler(Thing thing) {
53         super(thing);
54     }
55
56     @Override
57     public void handleCommand(ChannelUID channelUID, Command command) {
58         logger.debug("handleCommand, channel: {}, command: {}", channelUID, command);
59         if (command instanceof RefreshType) {
60             super.handleCommand(channelUID, command);
61         } else if (channelUID.getId().equals(CHANNEL_ALARM_STATUS)) {
62             handleAlarmState(command);
63             scheduleImmediateRefresh(REFRESH_DELAY_SECONDS);
64         } else {
65             logger.warn("Unknown command! {}", command);
66         }
67     }
68
69     private void handleAlarmState(Command command) {
70         String deviceId = config.getDeviceId();
71         VerisureSession session = getSession();
72         if (session != null) {
73             VerisureAlarmsDTO alarm = session.getVerisureThing(deviceId, getVerisureThingClass());
74             if (alarm != null) {
75                 BigDecimal installationId = alarm.getSiteId();
76                 String pinCode = session.getPinCode(installationId);
77
78                 if (pinCode != null) {
79                     String url = START_GRAPHQL;
80                     String operation, state = "";
81
82                     switch (command.toString()) {
83                         case "DISARMED":
84                             operation = "disarm";
85                             state = "armStateDisarm";
86                             break;
87                         case "ARMED_HOME":
88                             operation = "armHome";
89                             state = "armStateArmHome";
90                             break;
91                         case "ARMED_AWAY":
92                             operation = "armAway";
93                             state = "armStateArmAway";
94                             break;
95                         default:
96                             logger.warn("Unknown alarm command: {}", command);
97                             return;
98                     }
99
100                     ArrayList<AlarmDTO> list = new ArrayList<>();
101                     AlarmDTO alarmJSON = new AlarmDTO();
102                     VariablesDTO variables = new VariablesDTO();
103
104                     variables.setCode(pinCode);
105                     variables.setGiid(installationId.toString());
106                     alarmJSON.setVariables(variables);
107                     alarmJSON.setOperationName(operation);
108                     String query = "mutation " + operation + "($giid: String!, $code: String!) {\n  " + state
109                             + "(giid: $giid, code: $code)\n}\n";
110                     alarmJSON.setQuery(query);
111                     list.add(alarmJSON);
112
113                     String queryQLAlarmSetState = gson.toJson(list);
114                     logger.debug("Trying to set alarm state to {} with URL {} and data {}", operation, url,
115                             queryQLAlarmSetState);
116
117                     int httpResultCode = session.sendCommand(url, queryQLAlarmSetState, installationId);
118                     if (httpResultCode == HttpStatus.OK_200) {
119                         logger.debug("Alarm status successfully changed!");
120                     } else {
121                         logger.warn("Could not send command, HTTP result code: {}", httpResultCode);
122                     }
123                 } else {
124                     logger.warn("PIN code is not configured! Mandatory to control Alarm!");
125                 }
126             }
127         }
128     }
129
130     @Override
131     public Class<VerisureAlarmsDTO> getVerisureThingClass() {
132         return VerisureAlarmsDTO.class;
133     }
134
135     @Override
136     public synchronized void update(VerisureAlarmsDTO thing) {
137         updateAlarmState(thing);
138         updateStatus(ThingStatus.ONLINE);
139     }
140
141     private void updateAlarmState(VerisureAlarmsDTO alarmsJSON) {
142         ArmState armState = alarmsJSON.getData().getInstallation().getArmState();
143         String alarmStatus = armState.getStatusType();
144         if (alarmStatus != null) {
145             getThing().getChannels().stream().map(Channel::getUID)
146                     .filter(channelUID -> isLinked(channelUID) && !channelUID.getId().equals("timestamp"))
147                     .forEach(channelUID -> {
148                         State state = getValue(channelUID.getId(), armState);
149                         updateState(channelUID, state);
150                     });
151             updateTimeStamp(armState.getDate());
152             updateInstallationChannels(alarmsJSON);
153         } else {
154             logger.warn("Alarm status is null!");
155         }
156     }
157
158     public State getValue(String channelId, ArmState armState) {
159         switch (channelId) {
160             case CHANNEL_ALARM_STATUS:
161                 return new StringType(armState.getStatusType());
162             case CHANNEL_CHANGED_BY_USER:
163                 return new StringType(armState.getName());
164             case CHANNEL_CHANGED_VIA:
165                 return new StringType(armState.getChangedVia());
166         }
167         return UnDefType.UNDEF;
168     }
169
170     private static class AlarmDTO {
171
172         @SuppressWarnings("unused")
173         private @Nullable String operationName;
174         @SuppressWarnings("unused")
175         private VariablesDTO variables = new VariablesDTO();
176         @SuppressWarnings("unused")
177         private @Nullable String query;
178
179         public void setOperationName(String operationName) {
180             this.operationName = operationName;
181         }
182
183         public void setVariables(VariablesDTO variables) {
184             this.variables = variables;
185         }
186
187         public void setQuery(String query) {
188             this.query = query;
189         }
190     }
191
192     private static class VariablesDTO {
193
194         @SuppressWarnings("unused")
195         private @Nullable String giid;
196         @SuppressWarnings("unused")
197         private @Nullable String code;
198
199         public void setGiid(String giid) {
200             this.giid = giid;
201         }
202
203         public void setCode(String code) {
204             this.code = code;
205         }
206     }
207
208     @Override
209     public void updateTriggerChannel(String event) {
210         logger.debug("ThingHandler trigger event {}", event);
211         triggerChannel(CHANNEL_SMARTLOCK_TRIGGER_CHANNEL, event);
212     }
213 }