2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
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
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.verisure.internal.handler;
15 import static org.openhab.binding.verisure.internal.VerisureBindingConstants.*;
17 import java.math.BigDecimal;
18 import java.util.ArrayList;
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.eclipse.jdt.annotation.Nullable;
23 import org.eclipse.jetty.http.HttpStatus;
24 import org.openhab.binding.verisure.internal.VerisureSession;
25 import org.openhab.binding.verisure.internal.dto.VerisureAlarmsDTO;
26 import org.openhab.binding.verisure.internal.dto.VerisureAlarmsDTO.ArmState;
27 import org.openhab.core.library.types.StringType;
28 import org.openhab.core.thing.Channel;
29 import org.openhab.core.thing.ChannelUID;
30 import org.openhab.core.thing.Thing;
31 import org.openhab.core.thing.ThingStatus;
32 import org.openhab.core.thing.ThingTypeUID;
33 import org.openhab.core.types.Command;
34 import org.openhab.core.types.RefreshType;
35 import org.openhab.core.types.State;
36 import org.openhab.core.types.UnDefType;
39 * Handler for the Alarm Device thing type that Verisure provides.
41 * @author Jan Gustafsson - Initial contribution
45 public class VerisureAlarmThingHandler extends VerisureThingHandler<VerisureAlarmsDTO> {
47 public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Set.of(THING_TYPE_ALARM);
49 private static final int REFRESH_DELAY_SECONDS = 10;
51 public VerisureAlarmThingHandler(Thing thing) {
56 public void handleCommand(ChannelUID channelUID, Command command) {
57 logger.debug("handleCommand, channel: {}, command: {}", channelUID, command);
58 if (command instanceof RefreshType) {
59 super.handleCommand(channelUID, command);
60 } else if (channelUID.getId().equals(CHANNEL_ALARM_STATUS)) {
61 handleAlarmState(command);
62 scheduleImmediateRefresh(REFRESH_DELAY_SECONDS);
64 logger.warn("Unknown command! {}", command);
68 private void handleAlarmState(Command command) {
69 String deviceId = config.getDeviceId();
70 VerisureSession session = getSession();
71 if (session != null) {
72 VerisureAlarmsDTO alarm = session.getVerisureThing(deviceId, getVerisureThingClass());
74 BigDecimal installationId = alarm.getSiteId();
75 String pinCode = session.getPinCode(installationId);
77 if (pinCode != null) {
78 String url = START_GRAPHQL;
79 String operation, state = "";
81 switch (command.toString()) {
84 state = "armStateDisarm";
87 operation = "armHome";
88 state = "armStateArmHome";
91 operation = "armAway";
92 state = "armStateArmAway";
95 logger.warn("Unknown alarm command: {}", command);
99 ArrayList<AlarmDTO> list = new ArrayList<>();
100 AlarmDTO alarmJSON = new AlarmDTO();
101 VariablesDTO variables = new VariablesDTO();
103 variables.setCode(pinCode);
104 variables.setGiid(installationId.toString());
105 alarmJSON.setVariables(variables);
106 alarmJSON.setOperationName(operation);
107 String query = "mutation " + operation + "($giid: String!, $code: String!) {\n " + state
108 + "(giid: $giid, code: $code)\n}\n";
109 alarmJSON.setQuery(query);
112 String queryQLAlarmSetState = gson.toJson(list);
113 logger.debug("Trying to set alarm state to {} with URL {} and data {}", operation, url,
114 queryQLAlarmSetState);
116 int httpResultCode = session.sendCommand(url, queryQLAlarmSetState, installationId);
117 if (httpResultCode == HttpStatus.OK_200) {
118 logger.debug("Alarm status successfully changed!");
120 logger.warn("Could not send command, HTTP result code: {}", httpResultCode);
123 logger.warn("PIN code is not configured! Mandatory to control Alarm!");
130 public Class<VerisureAlarmsDTO> getVerisureThingClass() {
131 return VerisureAlarmsDTO.class;
135 public synchronized void update(VerisureAlarmsDTO thing) {
136 updateAlarmState(thing);
137 updateStatus(ThingStatus.ONLINE);
140 private void updateAlarmState(VerisureAlarmsDTO alarmsJSON) {
141 ArmState armState = alarmsJSON.getData().getInstallation().getArmState();
142 String alarmStatus = armState.getStatusType();
143 if (alarmStatus != null) {
144 getThing().getChannels().stream().map(Channel::getUID)
145 .filter(channelUID -> isLinked(channelUID) && !"timestamp".equals(channelUID.getId()))
146 .forEach(channelUID -> {
147 State state = getValue(channelUID.getId(), armState);
148 updateState(channelUID, state);
150 updateTimeStamp(armState.getDate());
151 updateInstallationChannels(alarmsJSON);
153 logger.warn("Alarm status is null!");
157 public State getValue(String channelId, ArmState armState) {
159 case CHANNEL_ALARM_STATUS:
160 return new StringType(armState.getStatusType());
161 case CHANNEL_CHANGED_BY_USER:
162 return new StringType(armState.getName());
163 case CHANNEL_CHANGED_VIA:
164 return new StringType(armState.getChangedVia());
166 return UnDefType.UNDEF;
169 private static class AlarmDTO {
171 @SuppressWarnings("unused")
172 private @Nullable String operationName;
173 @SuppressWarnings("unused")
174 private VariablesDTO variables = new VariablesDTO();
175 @SuppressWarnings("unused")
176 private @Nullable String query;
178 public void setOperationName(String operationName) {
179 this.operationName = operationName;
182 public void setVariables(VariablesDTO variables) {
183 this.variables = variables;
186 public void setQuery(String query) {
191 private static class VariablesDTO {
193 @SuppressWarnings("unused")
194 private @Nullable String giid;
195 @SuppressWarnings("unused")
196 private @Nullable String code;
198 public void setGiid(String giid) {
202 public void setCode(String code) {
208 public void updateTriggerChannel(String event) {
209 logger.debug("ThingHandler trigger event {}", event);
210 triggerChannel(CHANNEL_SMARTLOCK_TRIGGER_CHANNEL, event);