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