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