]> git.basschouten.com Git - openhab-addons.git/blob
b75ff8cd4361f9cca2cbe744205b96bb3a886623
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2021 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.tado.internal.adapter;
14
15 import java.math.BigDecimal;
16 import java.time.OffsetDateTime;
17
18 import org.openhab.binding.tado.internal.TadoBindingConstants.HvacMode;
19 import org.openhab.binding.tado.internal.TadoBindingConstants.OperationMode;
20 import org.openhab.binding.tado.internal.TadoBindingConstants.TemperatureUnit;
21 import org.openhab.binding.tado.internal.api.model.AcPowerDataPoint;
22 import org.openhab.binding.tado.internal.api.model.ActivityDataPoints;
23 import org.openhab.binding.tado.internal.api.model.CoolingZoneSetting;
24 import org.openhab.binding.tado.internal.api.model.GenericZoneSetting;
25 import org.openhab.binding.tado.internal.api.model.HeatingZoneSetting;
26 import org.openhab.binding.tado.internal.api.model.HotWaterZoneSetting;
27 import org.openhab.binding.tado.internal.api.model.Overlay;
28 import org.openhab.binding.tado.internal.api.model.OverlayTerminationConditionType;
29 import org.openhab.binding.tado.internal.api.model.Power;
30 import org.openhab.binding.tado.internal.api.model.SensorDataPoints;
31 import org.openhab.binding.tado.internal.api.model.TadoSystemType;
32 import org.openhab.binding.tado.internal.api.model.TemperatureDataPoint;
33 import org.openhab.binding.tado.internal.api.model.TemperatureObject;
34 import org.openhab.binding.tado.internal.api.model.TimerTerminationCondition;
35 import org.openhab.binding.tado.internal.api.model.ZoneState;
36 import org.openhab.core.library.types.DateTimeType;
37 import org.openhab.core.library.types.DecimalType;
38 import org.openhab.core.library.types.OnOffType;
39 import org.openhab.core.library.types.QuantityType;
40 import org.openhab.core.library.types.StringType;
41 import org.openhab.core.library.unit.ImperialUnits;
42 import org.openhab.core.library.unit.SIUnits;
43 import org.openhab.core.types.State;
44 import org.openhab.core.types.UnDefType;
45
46 /**
47  * Adapter from API-level zone state to the binding's item-based zone state.
48  *
49  * @author Dennis Frommknecht - Initial contribution
50  * @author Andrew Fiddian-Green - Added Low Battery Alarm, A/C Power and Open Window channels
51  * 
52  */
53 public class TadoZoneStateAdapter {
54     private ZoneState zoneState;
55     private TemperatureUnit temperatureUnit;
56
57     public TadoZoneStateAdapter(ZoneState zoneState, TemperatureUnit temperatureUnit) {
58         this.zoneState = zoneState;
59         this.temperatureUnit = temperatureUnit;
60     }
61
62     public State getInsideTemperature() {
63         SensorDataPoints sensorDataPoints = zoneState.getSensorDataPoints();
64         return toTemperatureState(sensorDataPoints.getInsideTemperature(), temperatureUnit);
65     }
66
67     public DecimalType getHumidity() {
68         SensorDataPoints sensorDataPoints = zoneState.getSensorDataPoints();
69         return sensorDataPoints.getHumidity() != null ? toDecimalType(sensorDataPoints.getHumidity().getPercentage())
70                 : null;
71     }
72
73     public DecimalType getHeatingPower() {
74         ActivityDataPoints dataPoints = zoneState.getActivityDataPoints();
75         return dataPoints.getHeatingPower() != null ? toDecimalType(dataPoints.getHeatingPower().getPercentage())
76                 : DecimalType.ZERO;
77     }
78
79     public OnOffType getAcPower() {
80         ActivityDataPoints dataPoints = zoneState.getActivityDataPoints();
81         AcPowerDataPoint acPower = dataPoints.getAcPower();
82         if (acPower != null) {
83             String acPowerValue = acPower.getValue();
84             if (acPowerValue != null) {
85                 return OnOffType.from(acPowerValue);
86             }
87         }
88         return null;
89     }
90
91     public StringType getMode() {
92         GenericZoneSetting setting = zoneState.getSetting();
93
94         if (!isPowerOn()) {
95             return StringType.valueOf(HvacMode.OFF.name());
96         } else if (setting.getType() == TadoSystemType.HEATING || setting.getType() == TadoSystemType.HOT_WATER) {
97             return StringType.valueOf(HvacMode.HEAT.name());
98         } else {
99             return StringType.valueOf(((CoolingZoneSetting) setting).getMode().getValue());
100         }
101     }
102
103     public State getTargetTemperature() {
104         switch (zoneState.getSetting().getType()) {
105             case HEATING:
106                 return toTemperatureState(((HeatingZoneSetting) zoneState.getSetting()).getTemperature(),
107                         temperatureUnit);
108             case AIR_CONDITIONING:
109                 return toTemperatureState(((CoolingZoneSetting) zoneState.getSetting()).getTemperature(),
110                         temperatureUnit);
111             case HOT_WATER:
112                 return toTemperatureState(((HotWaterZoneSetting) zoneState.getSetting()).getTemperature(),
113                         temperatureUnit);
114             default:
115                 return UnDefType.UNDEF;
116         }
117     }
118
119     public State getFanSpeed() {
120         if (zoneState.getSetting().getType() == TadoSystemType.AIR_CONDITIONING) {
121             CoolingZoneSetting setting = (CoolingZoneSetting) zoneState.getSetting();
122             return setting.getFanSpeed() != null ? StringType.valueOf(setting.getFanSpeed().getValue())
123                     : UnDefType.NULL;
124         } else {
125             return UnDefType.UNDEF;
126         }
127     }
128
129     public State getSwing() {
130         if (zoneState.getSetting().getType() == TadoSystemType.AIR_CONDITIONING) {
131             CoolingZoneSetting setting = (CoolingZoneSetting) zoneState.getSetting();
132             if (setting.getSwing() == null) {
133                 return UnDefType.NULL;
134             } else if (setting.getSwing() == Power.ON) {
135                 return OnOffType.ON;
136             } else {
137                 return OnOffType.OFF;
138             }
139         } else {
140             return UnDefType.UNDEF;
141         }
142     }
143
144     public StringType getOperationMode() {
145         Overlay overlay = zoneState.getOverlay();
146         if (overlay != null) {
147             switch (overlay.getTermination().getType()) {
148                 case MANUAL:
149                     return new StringType(OperationMode.MANUAL.name());
150                 case TIMER:
151                     return new StringType(OperationMode.TIMER.name());
152                 case TADO_MODE:
153                     return new StringType(OperationMode.UNTIL_CHANGE.name());
154             }
155         }
156
157         return new StringType(OperationMode.SCHEDULE.name());
158     }
159
160     public DecimalType getRemainingTimerDuration() {
161         Overlay overlay = zoneState.getOverlay();
162         if (overlay != null && overlay.getTermination().getType() == OverlayTerminationConditionType.TIMER) {
163             TimerTerminationCondition timerTerminationCondition = (TimerTerminationCondition) overlay.getTermination();
164
165             Integer remainingTimeInSeconds = timerTerminationCondition.getRemainingTimeInSeconds();
166             // If there's a timer overlay, then the timer should never be smaller than 1
167             return new DecimalType((int) Math.max(1.0, Math.round(remainingTimeInSeconds / 60.0)));
168         }
169
170         return new DecimalType();
171     }
172
173     public State getOverlayExpiration() {
174         Overlay overlay = zoneState.getOverlay();
175         if (overlay == null || overlay.getTermination().getProjectedExpiry() == null) {
176             return UnDefType.UNDEF;
177         }
178
179         return toDateTimeType(overlay.getTermination().getProjectedExpiry());
180     }
181
182     public boolean isPowerOn() {
183         Power power = Power.OFF;
184         GenericZoneSetting setting = zoneState.getSetting();
185
186         switch (setting.getType()) {
187             case HEATING:
188                 power = ((HeatingZoneSetting) setting).getPower();
189                 break;
190             case AIR_CONDITIONING:
191                 power = ((CoolingZoneSetting) setting).getPower();
192                 break;
193             case HOT_WATER:
194                 power = ((HotWaterZoneSetting) setting).getPower();
195                 break;
196         }
197
198         return power.getValue().equals("ON");
199     }
200
201     private static DecimalType toDecimalType(double value) {
202         BigDecimal decimal = new BigDecimal(value).setScale(2, BigDecimal.ROUND_HALF_UP);
203         return new DecimalType(decimal);
204     }
205
206     private static DateTimeType toDateTimeType(OffsetDateTime offsetDateTime) {
207         return new DateTimeType(offsetDateTime.toZonedDateTime());
208     }
209
210     private static State toTemperatureState(TemperatureObject temperature, TemperatureUnit temperatureUnit) {
211         if (temperature == null) {
212             return UnDefType.NULL;
213         }
214
215         return temperatureUnit == TemperatureUnit.FAHRENHEIT
216                 ? new QuantityType<>(temperature.getFahrenheit(), ImperialUnits.FAHRENHEIT)
217                 : new QuantityType<>(temperature.getCelsius(), SIUnits.CELSIUS);
218     }
219
220     private static State toTemperatureState(TemperatureDataPoint temperature, TemperatureUnit temperatureUnit) {
221         if (temperature == null) {
222             return UnDefType.NULL;
223         }
224
225         return temperatureUnit == TemperatureUnit.FAHRENHEIT
226                 ? new QuantityType<>(temperature.getFahrenheit(), ImperialUnits.FAHRENHEIT)
227                 : new QuantityType<>(temperature.getCelsius(), SIUnits.CELSIUS);
228     }
229
230     public State getOpenWindowDetected() {
231         Boolean openWindowDetected = zoneState.isOpenWindowDetected();
232         if (openWindowDetected != null) {
233             return OnOffType.from(openWindowDetected);
234         }
235         return OnOffType.OFF;
236     }
237 }