]> git.basschouten.com Git - openhab-addons.git/blob
d9668152490265bccd5181fd0c54b7d27bc82f0f
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 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.io.homekit.internal.accessories;
14
15 import static org.openhab.io.homekit.internal.HomekitCharacteristicType.CURRENT_DOOR_STATE;
16 import static org.openhab.io.homekit.internal.HomekitCharacteristicType.OBSTRUCTION_STATUS;
17 import static org.openhab.io.homekit.internal.HomekitCharacteristicType.TARGET_DOOR_STATE;
18
19 import java.util.List;
20 import java.util.Optional;
21 import java.util.concurrent.CompletableFuture;
22
23 import org.openhab.core.items.Item;
24 import org.openhab.core.library.items.StringItem;
25 import org.openhab.core.library.items.SwitchItem;
26 import org.openhab.core.library.types.OnOffType;
27 import org.openhab.core.library.types.OpenClosedType;
28 import org.openhab.core.library.types.StringType;
29 import org.openhab.io.homekit.internal.HomekitAccessoryUpdater;
30 import org.openhab.io.homekit.internal.HomekitSettings;
31 import org.openhab.io.homekit.internal.HomekitTaggedItem;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34
35 import io.github.hapjava.accessories.GarageDoorOpenerAccessory;
36 import io.github.hapjava.characteristics.HomekitCharacteristicChangeCallback;
37 import io.github.hapjava.characteristics.impl.garagedoor.CurrentDoorStateEnum;
38 import io.github.hapjava.characteristics.impl.garagedoor.TargetDoorStateEnum;
39 import io.github.hapjava.services.impl.GarageDoorOpenerService;
40
41 /**
42  * Implements Garage Door Opener
43  *
44  * @author Eugen Freiter - Initial contribution
45  */
46 public class HomekitGarageDoorOpenerImpl extends AbstractHomekitAccessoryImpl implements GarageDoorOpenerAccessory {
47     private final Logger logger = LoggerFactory.getLogger(HomekitGarageDoorOpenerImpl.class);
48     private final BooleanItemReader obstructionReader;
49
50     public HomekitGarageDoorOpenerImpl(HomekitTaggedItem taggedItem, List<HomekitTaggedItem> mandatoryCharacteristics,
51             HomekitAccessoryUpdater updater, HomekitSettings settings) throws IncompleteAccessoryException {
52         super(taggedItem, mandatoryCharacteristics, updater, settings);
53         obstructionReader = createBooleanReader(OBSTRUCTION_STATUS, OnOffType.ON, OpenClosedType.OPEN);
54         getServices().add(new GarageDoorOpenerService(this));
55     }
56
57     @Override
58     public CompletableFuture<CurrentDoorStateEnum> getCurrentDoorState() {
59         final Optional<HomekitTaggedItem> characteristic = getCharacteristic(CURRENT_DOOR_STATE);
60         final HomekitSettings settings = getSettings();
61         String stringValue = settings.doorCurrentStateClosed;
62         if (characteristic.isPresent()) {
63             stringValue = characteristic.get().getItem().getState().toString();
64         } else {
65             logger.warn("Missing mandatory characteristic {}", CURRENT_DOOR_STATE);
66         }
67         CurrentDoorStateEnum mode;
68
69         if (stringValue.equalsIgnoreCase(settings.doorCurrentStateClosed)) {
70             mode = CurrentDoorStateEnum.CLOSED;
71         } else if (stringValue.equalsIgnoreCase(settings.doorCurrentStateClosing)) {
72             mode = CurrentDoorStateEnum.CLOSING;
73         } else if (stringValue.equalsIgnoreCase(settings.doorCurrentStateOpen)) {
74             mode = CurrentDoorStateEnum.OPEN;
75         } else if (stringValue.equalsIgnoreCase(settings.doorCurrentStateOpening)) {
76             mode = CurrentDoorStateEnum.OPENING;
77         } else if (stringValue.equalsIgnoreCase(settings.doorCurrentStateStopped)) {
78             mode = CurrentDoorStateEnum.SOPPED;
79         } else if (stringValue.equals("UNDEF") || stringValue.equals("NULL")) {
80             logger.warn("Current door state not available. Relaying value of CLOSED to HomeKit");
81             mode = CurrentDoorStateEnum.CLOSED;
82         } else {
83             logger.warn("Unrecognized current door state: {}. Expected {}, {}, {}, {} or {} strings in value.",
84                     stringValue, settings.doorCurrentStateClosed, settings.doorCurrentStateClosing,
85                     settings.doorCurrentStateOpen, settings.doorCurrentStateOpening, settings.doorCurrentStateStopped);
86             mode = CurrentDoorStateEnum.CLOSED;
87         }
88         return CompletableFuture.completedFuture(mode);
89     }
90
91     @Override
92     public CompletableFuture<TargetDoorStateEnum> getTargetDoorState() {
93         final Optional<HomekitTaggedItem> characteristic = getCharacteristic(TARGET_DOOR_STATE);
94         Item item;
95
96         if (characteristic.isPresent()) {
97             item = characteristic.get().getItem();
98         } else {
99             logger.warn("Missing mandatory characteristic {}", TARGET_DOOR_STATE);
100             return CompletableFuture.completedFuture(TargetDoorStateEnum.CLOSED);
101         }
102         TargetDoorStateEnum mode;
103
104         if (item instanceof SwitchItem) {
105             mode = item.getState() == OnOffType.ON ? TargetDoorStateEnum.OPEN : TargetDoorStateEnum.CLOSED;
106         } else if (item instanceof StringItem) {
107             final HomekitSettings settings = getSettings();
108             final String stringValue = item.getState().toString();
109             if (stringValue.equalsIgnoreCase(settings.doorTargetStateClosed)) {
110                 mode = TargetDoorStateEnum.CLOSED;
111             } else if (stringValue.equalsIgnoreCase(settings.doorTargetStateOpen)) {
112                 mode = TargetDoorStateEnum.OPEN;
113             } else {
114                 logger.warn(
115                         "Unsupported value {} for {}. Only {} and {} supported. Check HomeKit settings if you want to change the mapping",
116                         stringValue, item.getName(), settings.doorTargetStateClosed, settings.doorTargetStateOpen);
117                 mode = TargetDoorStateEnum.CLOSED;
118             }
119         } else {
120             logger.warn("Unsupported item type {} for {}. Only Switch and String are supported", item.getType(),
121                     item.getName());
122             mode = TargetDoorStateEnum.CLOSED;
123         }
124         return CompletableFuture.completedFuture(mode);
125     }
126
127     @Override
128     public CompletableFuture<Boolean> getObstructionDetected() {
129         return CompletableFuture.completedFuture(obstructionReader.getValue());
130     }
131
132     @Override
133     public CompletableFuture<Void> setTargetDoorState(TargetDoorStateEnum targetDoorStateEnum) {
134         final Optional<HomekitTaggedItem> characteristic = getCharacteristic(TARGET_DOOR_STATE);
135         Item item;
136         if (characteristic.isPresent()) {
137             item = characteristic.get().getItem();
138         } else {
139             logger.warn("Missing mandatory characteristic {}", TARGET_DOOR_STATE);
140             return CompletableFuture.completedFuture(null);
141         }
142
143         if (item instanceof SwitchItem) {
144             ((SwitchItem) item).send(OnOffType.from(targetDoorStateEnum == TargetDoorStateEnum.OPEN));
145         } else if (item instanceof StringItem) {
146             final HomekitSettings settings = getSettings();
147             ((StringItem) item)
148                     .send(new StringType(targetDoorStateEnum == TargetDoorStateEnum.OPEN ? settings.doorTargetStateOpen
149                             : settings.doorTargetStateClosed));
150         } else {
151             logger.warn("Unsupported item type {} for {}. Only Switch and String are supported", item.getType(),
152                     item.getName());
153         }
154         return CompletableFuture.completedFuture(null);
155     }
156
157     @Override
158     public void subscribeCurrentDoorState(HomekitCharacteristicChangeCallback callback) {
159         subscribe(CURRENT_DOOR_STATE, callback);
160     }
161
162     @Override
163     public void subscribeTargetDoorState(HomekitCharacteristicChangeCallback callback) {
164         subscribe(TARGET_DOOR_STATE, callback);
165     }
166
167     @Override
168     public void subscribeObstructionDetected(HomekitCharacteristicChangeCallback callback) {
169         subscribe(OBSTRUCTION_STATUS, callback);
170     }
171
172     @Override
173     public void unsubscribeCurrentDoorState() {
174         unsubscribe(CURRENT_DOOR_STATE);
175     }
176
177     @Override
178     public void unsubscribeTargetDoorState() {
179         unsubscribe(TARGET_DOOR_STATE);
180     }
181
182     @Override
183     public void unsubscribeObstructionDetected() {
184         unsubscribe(OBSTRUCTION_STATUS);
185     }
186 }