2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
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
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.avmfritz.internal.dto;
15 import static org.openhab.binding.avmfritz.internal.AVMFritzBindingConstants.*;
17 import java.math.BigDecimal;
18 import java.math.RoundingMode;
20 import javax.xml.bind.annotation.XmlAccessType;
21 import javax.xml.bind.annotation.XmlAccessorType;
22 import javax.xml.bind.annotation.XmlRootElement;
24 import org.eclipse.jdt.annotation.Nullable;
27 * See {@link DeviceListModel}.
29 * @author Christoph Weitkamp - Initial contribution
30 * @author Christoph Weitkamp - Added support for AVM FRITZ!DECT 300 and Comet DECT
31 * @author Christoph Weitkamp - Added channel 'battery_level'
33 @XmlAccessorType(XmlAccessType.FIELD)
34 @XmlRootElement(name = "hkr")
35 public class HeatingModel implements BatteryModel {
36 public static final BigDecimal TEMP_FACTOR = new BigDecimal("0.5");
37 public static final BigDecimal BIG_DECIMAL_TWO = new BigDecimal("2.0");
38 public static final BigDecimal TEMP_CELSIUS_MIN = new BigDecimal("8.0");
39 public static final BigDecimal TEMP_CELSIUS_MAX = new BigDecimal("28.0");
40 public static final BigDecimal TEMP_FRITZ_MIN = new BigDecimal("16.0");
41 public static final BigDecimal TEMP_FRITZ_MAX = new BigDecimal("56.0");
42 public static final BigDecimal TEMP_FRITZ_OFF = new BigDecimal("253.0");
43 public static final BigDecimal TEMP_FRITZ_ON = new BigDecimal("254.0");
44 public static final BigDecimal TEMP_FRITZ_UNDEFINED = new BigDecimal("255.0");
46 private BigDecimal tist;
47 private BigDecimal tsoll;
48 private BigDecimal absenk;
49 private BigDecimal komfort;
50 private BigDecimal lock;
51 private BigDecimal devicelock;
52 private String errorcode;
53 private BigDecimal batterylow;
54 private @Nullable BigDecimal windowopenactiv;
55 private @Nullable BigDecimal windowopenactiveendtime;
56 private @Nullable BigDecimal boostactive;
57 private @Nullable BigDecimal boostactiveendtime;
58 private BigDecimal battery;
59 private NextChangeModel nextchange;
60 private BigDecimal summeractive;
61 private BigDecimal holidayactive;
63 public BigDecimal getTist() {
67 public void setTist(BigDecimal tist) {
71 public BigDecimal getTsoll() {
75 public void setTsoll(BigDecimal tsoll) {
79 public BigDecimal getKomfort() {
83 public void setKomfort(BigDecimal komfort) {
84 this.komfort = komfort;
87 public BigDecimal getAbsenk() {
91 public void setAbsenk(BigDecimal absenk) {
95 public String getMode() {
96 if (BigDecimal.ONE.equals(getHolidayactive())) {
98 } else if (getNextchange() != null && getNextchange().getEndperiod() != 0) {
105 public String getRadiatorMode() {
108 } else if (TEMP_FRITZ_ON.compareTo(tsoll) == 0) {
110 } else if (TEMP_FRITZ_OFF.compareTo(tsoll) == 0) {
112 } else if (BigDecimal.ONE.equals(getWindowopenactiv())) {
113 return MODE_WINDOW_OPEN;
114 } else if (komfort != null && komfort.compareTo(tsoll) == 0) {
116 } else if (absenk != null && absenk.compareTo(tsoll) == 0) {
118 } else if (BigDecimal.ONE.equals(getBoostactive()) || TEMP_FRITZ_MAX.compareTo(tsoll) == 0) {
125 public BigDecimal getLock() {
129 public void setLock(BigDecimal lock) {
133 public BigDecimal getDevicelock() {
137 public void setDevicelock(BigDecimal devicelock) {
138 this.devicelock = devicelock;
141 public String getErrorcode() {
145 public void setErrorcode(String errorcode) {
146 this.errorcode = errorcode;
150 public BigDecimal getBatterylow() {
154 public void setBatterylow(BigDecimal batterylow) {
155 this.batterylow = batterylow;
158 public @Nullable BigDecimal getWindowopenactiv() {
159 return windowopenactiv;
162 public @Nullable BigDecimal getWindowopenactiveendtime() {
163 return windowopenactiveendtime;
166 public void setWindowopenactiv(BigDecimal windowopenactiv) {
167 this.windowopenactiv = windowopenactiv;
170 public @Nullable BigDecimal getBoostactive() {
174 public @Nullable BigDecimal getBoostactiveendtime() {
175 return boostactiveendtime;
179 public BigDecimal getBattery() {
183 public void setBattery(BigDecimal battery) {
184 this.battery = battery;
187 public NextChangeModel getNextchange() {
191 public void setNextchange(NextChangeModel nextchange) {
192 this.nextchange = nextchange;
195 public BigDecimal getSummeractive() {
199 public void setSummeractive(BigDecimal summeractive) {
200 this.summeractive = summeractive;
203 public BigDecimal getHolidayactive() {
204 return holidayactive;
207 public void setHolidayactive(BigDecimal holidayactive) {
208 this.holidayactive = holidayactive;
212 public String toString() {
213 return new StringBuilder().append("[tist=").append(tist).append(",tsoll=").append(tsoll).append(",absenk=")
214 .append(absenk).append(",komfort=").append(komfort).append(",lock=").append(lock).append(",devicelock=")
215 .append(devicelock).append(",errorcode=").append(errorcode).append(",batterylow=").append(batterylow)
216 .append(",windowopenactiv=").append(windowopenactiv).append(",windowopenactiveendtime=")
217 .append(windowopenactiveendtime).append(",boostactive=").append(boostactive)
218 .append(",boostactiveendtime=").append(boostactiveendtime).append(",battery=").append(battery)
219 .append(",nextchange=").append(nextchange).append(",summeractive=").append(summeractive)
220 .append(",holidayactive=").append(holidayactive).append("]").toString();
224 * Converts a celsius value to a FRITZ!Box value.
225 * Valid celsius values: 8 to 28 °C > 16 to 56
226 * 16 <= 8°C, 17 = 8.5°C...... 56 >= 28°C, 254 = ON, 253 = OFF
228 * @param celsiusValue The celsius value to be converted
229 * @return The FRITZ!Box value
231 public static BigDecimal fromCelsius(BigDecimal celsiusValue) {
232 if (celsiusValue == null) {
233 return BigDecimal.ZERO;
234 } else if (TEMP_CELSIUS_MIN.compareTo(celsiusValue) == 1) {
235 return TEMP_FRITZ_MIN;
236 } else if (TEMP_CELSIUS_MAX.compareTo(celsiusValue) == -1) {
237 return TEMP_FRITZ_MAX;
239 return BIG_DECIMAL_TWO.multiply(celsiusValue);
243 * Converts a FRITZ!Box value to a celsius value.
245 * @param fritzValue The FRITZ!Box value to be converted
246 * @return The celsius value
248 public static BigDecimal toCelsius(BigDecimal fritzValue) {
249 if (fritzValue == null) {
250 return BigDecimal.ZERO;
251 } else if (TEMP_FRITZ_ON.compareTo(fritzValue) == 0) {
252 return TEMP_CELSIUS_MAX.add(BIG_DECIMAL_TWO);
253 } else if (TEMP_FRITZ_OFF.compareTo(fritzValue) == 0) {
254 return TEMP_CELSIUS_MIN.subtract(BIG_DECIMAL_TWO);
256 return TEMP_FACTOR.multiply(fritzValue);
260 * Normalizes a celsius value.
261 * Valid celsius steps: 0.5°C
263 * @param celsiusValue The celsius value to be normalized
264 * @return The normalized celsius value
266 public static BigDecimal normalizeCelsius(BigDecimal celsiusValue) {
267 BigDecimal divisor = celsiusValue.divide(TEMP_FACTOR, 0, RoundingMode.HALF_UP);
268 return TEMP_FACTOR.multiply(divisor);
271 @XmlAccessorType(XmlAccessType.FIELD)
272 public static class NextChangeModel {
273 private int endperiod;
274 private BigDecimal tchange;
276 public int getEndperiod() {
280 public void setEndperiod(int endperiod) {
281 this.endperiod = endperiod;
284 public BigDecimal getTchange() {
288 public void setTchange(BigDecimal tchange) {
289 this.tchange = tchange;
293 public String toString() {
294 return new StringBuilder().append("[endperiod=").append(endperiod).append(",tchange=").append(tchange)
295 .append("]").toString();