]> git.basschouten.com Git - openhab-addons.git/blob
514c23166bdd8754dc85fcbac29c8e0245c0761d
[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.ACTIVE_STATUS;
16 import static org.openhab.io.homekit.internal.HomekitCharacteristicType.CURRENT_HEATER_COOLER_STATE;
17 import static org.openhab.io.homekit.internal.HomekitCharacteristicType.TARGET_HEATER_COOLER_STATE;
18
19 import java.util.EnumMap;
20 import java.util.List;
21 import java.util.Map;
22 import java.util.Optional;
23 import java.util.concurrent.CompletableFuture;
24
25 import org.eclipse.jdt.annotation.Nullable;
26 import org.openhab.core.items.GenericItem;
27 import org.openhab.core.library.items.StringItem;
28 import org.openhab.core.library.types.DecimalType;
29 import org.openhab.core.library.types.OnOffType;
30 import org.openhab.core.library.types.OpenClosedType;
31 import org.openhab.core.library.types.StringType;
32 import org.openhab.io.homekit.internal.HomekitAccessoryUpdater;
33 import org.openhab.io.homekit.internal.HomekitCharacteristicType;
34 import org.openhab.io.homekit.internal.HomekitSettings;
35 import org.openhab.io.homekit.internal.HomekitTaggedItem;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39 import io.github.hapjava.accessories.HeaterCoolerAccessory;
40 import io.github.hapjava.characteristics.HomekitCharacteristicChangeCallback;
41 import io.github.hapjava.characteristics.impl.heatercooler.CurrentHeaterCoolerStateEnum;
42 import io.github.hapjava.characteristics.impl.heatercooler.TargetHeaterCoolerStateEnum;
43 import io.github.hapjava.characteristics.impl.thermostat.TemperatureDisplayUnitCharacteristic;
44 import io.github.hapjava.characteristics.impl.thermostat.TemperatureDisplayUnitEnum;
45 import io.github.hapjava.services.impl.HeaterCoolerService;
46
47 /**
48  * Implements Heater Cooler
49  *
50  * @author Eugen Freiter - Initial contribution
51  */
52
53 public class HomekitHeaterCoolerImpl extends AbstractHomekitAccessoryImpl implements HeaterCoolerAccessory {
54     private final Logger logger = LoggerFactory.getLogger(HomekitHeaterCoolerImpl.class);
55     private final BooleanItemReader activeReader;
56     private final Map<CurrentHeaterCoolerStateEnum, String> currentStateMapping = new EnumMap<CurrentHeaterCoolerStateEnum, String>(
57             CurrentHeaterCoolerStateEnum.class) {
58         {
59             put(CurrentHeaterCoolerStateEnum.INACTIVE, "INACTIVE");
60             put(CurrentHeaterCoolerStateEnum.IDLE, "IDLE");
61             put(CurrentHeaterCoolerStateEnum.HEATING, "HEATING");
62             put(CurrentHeaterCoolerStateEnum.COOLING, "COOLING");
63         }
64     };
65     private final Map<TargetHeaterCoolerStateEnum, String> targetStateMapping = new EnumMap<TargetHeaterCoolerStateEnum, String>(
66             TargetHeaterCoolerStateEnum.class) {
67         {
68             put(TargetHeaterCoolerStateEnum.AUTO, "AUTO");
69             put(TargetHeaterCoolerStateEnum.HEAT, "HEAT");
70             put(TargetHeaterCoolerStateEnum.COOL, "COOL");
71         }
72     };
73
74     public HomekitHeaterCoolerImpl(HomekitTaggedItem taggedItem, List<HomekitTaggedItem> mandatoryCharacteristics,
75             HomekitAccessoryUpdater updater, HomekitSettings settings) throws IncompleteAccessoryException {
76         super(taggedItem, mandatoryCharacteristics, updater, settings);
77         activeReader = new BooleanItemReader(getItem(ACTIVE_STATUS, GenericItem.class)
78                 .orElseThrow(() -> new IncompleteAccessoryException(ACTIVE_STATUS)), OnOffType.ON, OpenClosedType.OPEN);
79         updateMapping(CURRENT_HEATER_COOLER_STATE, currentStateMapping);
80         updateMapping(TARGET_HEATER_COOLER_STATE, targetStateMapping);
81         final HeaterCoolerService service = new HeaterCoolerService(this);
82         service.addOptionalCharacteristic(new TemperatureDisplayUnitCharacteristic(this::getTemperatureDisplayUnit,
83                 this::setTemperatureDisplayUnit, this::subscribeTemperatureDisplayUnit,
84                 this::unsubscribeTemperatureDisplayUnit));
85         getServices().add(service);
86     }
87
88     @Override
89     public CompletableFuture<Double> getCurrentTemperature() {
90         final @Nullable DecimalType state = getStateAs(HomekitCharacteristicType.CURRENT_TEMPERATURE,
91                 DecimalType.class);
92         return CompletableFuture.completedFuture(state != null ? convertToCelsius(state.doubleValue()) : 0.0);
93     }
94
95     @Override
96     public CompletableFuture<Boolean> isActive() {
97         return CompletableFuture.completedFuture(activeReader.getValue());
98     }
99
100     @Override
101     public CompletableFuture<Void> setActive(boolean state) {
102         activeReader.setValue(state);
103         return CompletableFuture.completedFuture(null);
104     }
105
106     @Override
107     public CompletableFuture<CurrentHeaterCoolerStateEnum> getCurrentHeaterCoolerState() {
108         return CompletableFuture.completedFuture(getKeyFromMapping(CURRENT_HEATER_COOLER_STATE, currentStateMapping,
109                 CurrentHeaterCoolerStateEnum.INACTIVE));
110     }
111
112     @Override
113     public CompletableFuture<TargetHeaterCoolerStateEnum> getTargetHeaterCoolerState() {
114         return CompletableFuture.completedFuture(
115                 getKeyFromMapping(TARGET_HEATER_COOLER_STATE, targetStateMapping, TargetHeaterCoolerStateEnum.AUTO));
116     }
117
118     @Override
119     public CompletableFuture<Void> setTargetHeaterCoolerState(TargetHeaterCoolerStateEnum state) {
120         final Optional<HomekitTaggedItem> characteristic = getCharacteristic(
121                 HomekitCharacteristicType.TARGET_HEATER_COOLER_STATE);
122         if (characteristic.isPresent()) {
123             ((StringItem) characteristic.get().getItem()).send(new StringType(targetStateMapping.get(state)));
124         } else {
125             logger.warn("Missing mandatory characteristic {}",
126                     HomekitCharacteristicType.TARGET_HEATING_COOLING_STATE.getTag());
127         }
128         return CompletableFuture.completedFuture(null);
129     }
130
131     public CompletableFuture<TemperatureDisplayUnitEnum> getTemperatureDisplayUnit() {
132         return CompletableFuture
133                 .completedFuture(getSettings().useFahrenheitTemperature ? TemperatureDisplayUnitEnum.FAHRENHEIT
134                         : TemperatureDisplayUnitEnum.CELSIUS);
135     }
136
137     public void setTemperatureDisplayUnit(TemperatureDisplayUnitEnum value) {
138         // temperature unit set globally via binding setting and cannot be changed at item level.
139         // this method is intentionally empty.
140     }
141
142     @Override
143     public void subscribeCurrentHeaterCoolerState(HomekitCharacteristicChangeCallback callback) {
144         subscribe(HomekitCharacteristicType.CURRENT_HEATER_COOLER_STATE, callback);
145     }
146
147     @Override
148     public void unsubscribeCurrentHeaterCoolerState() {
149         unsubscribe(HomekitCharacteristicType.CURRENT_HEATER_COOLER_STATE);
150     }
151
152     @Override
153     public void subscribeTargetHeaterCoolerState(HomekitCharacteristicChangeCallback callback) {
154         subscribe(HomekitCharacteristicType.TARGET_HEATER_COOLER_STATE, callback);
155     }
156
157     @Override
158     public void unsubscribeTargetHeaterCoolerState() {
159         unsubscribe(HomekitCharacteristicType.TARGET_HEATER_COOLER_STATE);
160     }
161
162     @Override
163     public void subscribeActive(HomekitCharacteristicChangeCallback callback) {
164         subscribe(ACTIVE_STATUS, callback);
165     }
166
167     @Override
168     public void unsubscribeActive() {
169         unsubscribe(ACTIVE_STATUS);
170     }
171
172     @Override
173     public void subscribeCurrentTemperature(HomekitCharacteristicChangeCallback callback) {
174         subscribe(HomekitCharacteristicType.CURRENT_TEMPERATURE, callback);
175     }
176
177     @Override
178     public void unsubscribeCurrentTemperature() {
179         unsubscribe(HomekitCharacteristicType.CURRENT_TEMPERATURE);
180     }
181
182     public void subscribeTemperatureDisplayUnit(HomekitCharacteristicChangeCallback callback) {
183         // temperature unit set globally via binding setting and cannot be changed at item level.
184         // this method is intentionally empty
185     }
186
187     public void unsubscribeTemperatureDisplayUnit() {
188         // temperature unit set globally via binding setting and cannot be changed at item level.
189         // this method is intentionally empty
190     }
191 }