]> git.basschouten.com Git - openhab-addons.git/blob
2414ee0d821ab3ca7f9461946acc817209577a38
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 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.binding.draytonwiser.internal.handler;
14
15 import static org.openhab.binding.draytonwiser.internal.DraytonWiserBindingConstants.*;
16
17 import javax.measure.quantity.Time;
18
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.eclipse.jdt.annotation.Nullable;
21 import org.openhab.binding.draytonwiser.internal.api.DraytonWiserApiException;
22 import org.openhab.binding.draytonwiser.internal.model.DraytonWiserDTO;
23 import org.openhab.binding.draytonwiser.internal.model.RoomDTO;
24 import org.openhab.binding.draytonwiser.internal.model.RoomStatDTO;
25 import org.openhab.core.library.types.DecimalType;
26 import org.openhab.core.library.types.OnOffType;
27 import org.openhab.core.library.types.OpenClosedType;
28 import org.openhab.core.library.types.QuantityType;
29 import org.openhab.core.library.unit.SIUnits;
30 import org.openhab.core.library.unit.Units;
31 import org.openhab.core.thing.Thing;
32 import org.openhab.core.types.Command;
33 import org.openhab.core.types.State;
34 import org.openhab.core.types.UnDefType;
35
36 /**
37  * The {@link RoomHandler} is responsible for handling commands, which are
38  * sent to one of the channels.
39  *
40  * @author Andrew Schofield - Initial contribution
41  * @author Hilbrand Bouwkamp - Simplified handler to handle null data
42  */
43 @NonNullByDefault
44 public class RoomHandler extends DraytonWiserThingHandler<RoomDTO> {
45
46     private String name = "";
47
48     public RoomHandler(final Thing thing) {
49         super(thing);
50     }
51
52     @Override
53     public void initialize() {
54         super.initialize();
55         name = (String) getConfig().get("name");
56     }
57
58     @Override
59     protected void handleCommand(final String channelId, final Command command) throws DraytonWiserApiException {
60         switch (channelId) {
61             case CHANNEL_CURRENT_SETPOINT:
62                 if (command instanceof QuantityType quantityCommand) {
63                     setSetPoint(quantityCommand);
64                 }
65                 break;
66             case CHANNEL_MANUAL_MODE_STATE:
67                 if (command instanceof OnOffType) {
68                     setManualMode(OnOffType.ON.equals(command));
69                 }
70                 break;
71             case CHANNEL_ROOM_BOOST_DURATION:
72                 if (command instanceof DecimalType decimalCommand) {
73                     setBoostDuration(Math.round((decimalCommand.floatValue() * 60)));
74                 }
75                 break;
76             case CHANNEL_ROOM_WINDOW_STATE_DETECTION:
77                 if (command instanceof OnOffType) {
78                     setWindowStateDetection(OnOffType.ON.equals(command));
79                 }
80                 break;
81         }
82     }
83
84     @Override
85     protected void refresh() {
86         updateState(CHANNEL_CURRENT_TEMPERATURE, this::getTemperature);
87         updateState(CHANNEL_CURRENT_HUMIDITY, this::getHumidity);
88         updateState(CHANNEL_CURRENT_SETPOINT, this::getSetPoint);
89         updateState(CHANNEL_CURRENT_DEMAND, this::getDemand);
90         updateState(CHANNEL_HEAT_REQUEST, this::getHeatRequest);
91         updateState(CHANNEL_MANUAL_MODE_STATE, this::getManualModeState);
92         updateState(CHANNEL_ROOM_BOOSTED, this::getBoostedState);
93         updateState(CHANNEL_ROOM_BOOST_REMAINING, this::getBoostRemainingState);
94         updateState(CHANNEL_ROOM_WINDOW_STATE_DETECTION, this::getWindowDetectionState);
95         updateState(CHANNEL_ROOM_WINDOW_STATE, this::getWindowState);
96     }
97
98     @Override
99     protected @Nullable RoomDTO collectData(final DraytonWiserDTO domainDTOProxy) {
100         return domainDTOProxy.getRoomByName(name);
101     }
102
103     private State getSetPoint() {
104         return new QuantityType<>(getData().getCurrentSetPoint() / 10.0, SIUnits.CELSIUS);
105     }
106
107     private void setSetPoint(final QuantityType<?> command) throws DraytonWiserApiException {
108         if (getData().getId() != null) {
109             final QuantityType<?> value = command.toUnit(SIUnits.CELSIUS);
110
111             if (value != null) {
112                 final int newSetPoint = (int) Math.round(value.doubleValue() * 10);
113
114                 getApi().setRoomSetPoint(getData().getId(), newSetPoint);
115             }
116         }
117     }
118
119     private State getHumidity() {
120         if (getData().getId() != null && getData().getRoomStatId() != null) {
121             final RoomStatDTO roomStat = getDraytonWiserDTO().getRoomStat(getData().getRoomStatId());
122
123             if (roomStat != null) {
124                 final Integer humidity = roomStat.getMeasuredHumidity();
125
126                 return humidity == null ? UnDefType.UNDEF : new QuantityType<>(humidity, Units.PERCENT);
127             }
128         }
129         return UnDefType.UNDEF;
130     }
131
132     private State getTemperature() {
133         final int fullScaleTemp = getData().getCalculatedTemperature();
134
135         return OFFLINE_TEMPERATURE == fullScaleTemp ? UnDefType.UNDEF
136                 : new QuantityType<>(fullScaleTemp / 10.0, SIUnits.CELSIUS);
137     }
138
139     private State getDemand() {
140         return new QuantityType<>(getData().getPercentageDemand(), Units.PERCENT);
141     }
142
143     private State getHeatRequest() {
144         return OnOffType.from(getData().getControlOutputState());
145     }
146
147     private State getManualModeState() {
148         return OnOffType.from("MANUAL".equalsIgnoreCase(getData().getMode()));
149     }
150
151     private void setManualMode(final boolean manualMode) throws DraytonWiserApiException {
152         getApi().setRoomManualMode(getData().getId(), manualMode);
153     }
154
155     private void setWindowStateDetection(final boolean stateDetection) throws DraytonWiserApiException {
156         getApi().setRoomWindowStateDetection(getData().getId(), stateDetection);
157     }
158
159     private State getBoostedState() {
160         if (getData().getOverrideTimeoutUnixTime() != null && !"NONE".equalsIgnoreCase(getData().getOverrideType())) {
161             return OnOffType.ON;
162         }
163         updateState(CHANNEL_ROOM_BOOST_DURATION, DecimalType.ZERO);
164         return OnOffType.OFF;
165     }
166
167     private State getBoostRemainingState() {
168         final Integer overrideTimeout = getData().getOverrideTimeoutUnixTime();
169         if (overrideTimeout != null && !"NONE".equalsIgnoreCase(getData().getOverrideType())) {
170             return new QuantityType<Time>(overrideTimeout - (System.currentTimeMillis() / 1000L), Units.SECOND);
171         }
172         return new QuantityType<Time>(0, Units.SECOND);
173     }
174
175     private void setBoostDuration(final int durationMinutes) throws DraytonWiserApiException {
176         if (durationMinutes > 0) {
177             getApi().setRoomBoostActive(getData().getId(), getData().getCalculatedTemperature() + 20, durationMinutes);
178         } else {
179             getApi().setRoomBoostInactive(getData().getId());
180         }
181     }
182
183     private State getWindowDetectionState() {
184         return OnOffType.from(getData().getWindowDetectionActive());
185     }
186
187     private State getWindowState() {
188         if (getData().getWindowState() != null && "OPEN".equalsIgnoreCase(getData().getWindowState())) {
189             return OpenClosedType.OPEN;
190         }
191         return OpenClosedType.CLOSED;
192     }
193 }