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;
19 import java.util.Collections;
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;
40 * Handler for the Alarm Device thing type that Verisure provides.
42 * @author Jan Gustafsson - Initial contribution
46 public class VerisureAlarmThingHandler extends VerisureThingHandler<VerisureAlarmsDTO> {
48 public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Collections.singleton(THING_TYPE_ALARM);
50 private static final int REFRESH_DELAY_SECONDS = 10;
52 public VerisureAlarmThingHandler(Thing thing) {
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);
65 logger.warn("Unknown command! {}", command);
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());
75 BigDecimal installationId = alarm.getSiteId();
76 String pinCode = session.getPinCode(installationId);
78 if (pinCode != null) {
79 String url = START_GRAPHQL;
80 String operation, state = "";
82 switch (command.toString()) {
85 state = "armStateDisarm";
88 operation = "armHome";
89 state = "armStateArmHome";
92 operation = "armAway";
93 state = "armStateArmAway";
96 logger.warn("Unknown alarm command: {}", command);
100 ArrayList<AlarmDTO> list = new ArrayList<>();
101 AlarmDTO alarmJSON = new AlarmDTO();
102 VariablesDTO variables = new VariablesDTO();
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);
113 String queryQLAlarmSetState = gson.toJson(list);
114 logger.debug("Trying to set alarm state to {} with URL {} and data {}", operation, url,
115 queryQLAlarmSetState);
117 int httpResultCode = session.sendCommand(url, queryQLAlarmSetState, installationId);
118 if (httpResultCode == HttpStatus.OK_200) {
119 logger.debug("Alarm status successfully changed!");
121 logger.warn("Could not send command, HTTP result code: {}", httpResultCode);
124 logger.warn("PIN code is not configured! Mandatory to control Alarm!");
131 public Class<VerisureAlarmsDTO> getVerisureThingClass() {
132 return VerisureAlarmsDTO.class;
136 public synchronized void update(VerisureAlarmsDTO thing) {
137 updateAlarmState(thing);
138 updateStatus(ThingStatus.ONLINE);
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);
151 updateTimeStamp(armState.getDate());
152 updateInstallationChannels(alarmsJSON);
154 logger.warn("Alarm status is null!");
158 public State getValue(String channelId, ArmState armState) {
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());
167 return UnDefType.UNDEF;
170 private static class AlarmDTO {
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;
179 public void setOperationName(String operationName) {
180 this.operationName = operationName;
183 public void setVariables(VariablesDTO variables) {
184 this.variables = variables;
187 public void setQuery(String query) {
192 private static class VariablesDTO {
194 @SuppressWarnings("unused")
195 private @Nullable String giid;
196 @SuppressWarnings("unused")
197 private @Nullable String code;
199 public void setGiid(String giid) {
203 public void setCode(String code) {
209 public void updateTriggerChannel(String event) {
210 logger.debug("ThingHandler trigger event {}", event);
211 triggerChannel(CHANNEL_SMARTLOCK_TRIGGER_CHANNEL, event);