]> git.basschouten.com Git - openhab-addons.git/blob
a1a50d28a71a486d657fb01c0ea0aa1702eb0635
[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.mielecloud.internal.handler.channel;
14
15 import java.math.BigDecimal;
16 import java.text.NumberFormat;
17 import java.util.Locale;
18 import java.util.Optional;
19
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.openhab.binding.mielecloud.internal.webservice.api.Quantity;
22 import org.openhab.core.library.types.DecimalType;
23 import org.openhab.core.library.types.OnOffType;
24 import org.openhab.core.library.types.QuantityType;
25 import org.openhab.core.library.types.StringType;
26 import org.openhab.core.library.unit.SIUnits;
27 import org.openhab.core.types.State;
28 import org.openhab.core.types.UnDefType;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32 /**
33  * Utility class handling type conversions from Java types to channel types.
34  *
35  * @author Björn Lange - Initial Contribution
36  */
37 @NonNullByDefault
38 public final class ChannelTypeUtil {
39     private static final Logger LOGGER = LoggerFactory.getLogger(ChannelTypeUtil.class);
40
41     private ChannelTypeUtil() {
42         throw new IllegalStateException("ChannelTypeUtil cannot be instantiated.");
43     }
44
45     /**
46      * Converts an {@link Optional} of {@link String} to {@link State}.
47      */
48     public static State stringToState(Optional<String> value) {
49         return value.filter(v -> !v.isEmpty()).filter(v -> !v.equals("null")).map(v -> (State) new StringType(v))
50                 .orElse(UnDefType.UNDEF);
51     }
52
53     /**
54      * Converts an {@link Optional} of {@link Boolean} to {@link State}.
55      */
56     public static State booleanToState(Optional<Boolean> value) {
57         return value.map(v -> (State) OnOffType.from(v)).orElse(UnDefType.UNDEF);
58     }
59
60     /**
61      * Converts an {@link Optional} of {@link Integer} to {@link State}.
62      */
63     public static State intToState(Optional<Integer> value) {
64         return value.map(v -> (State) new DecimalType(new BigDecimal(v))).orElse(UnDefType.UNDEF);
65     }
66
67     /**
68      * Converts an {@link Optional} of {@link Long} to {@link State}.
69      */
70     public static State longToState(Optional<Long> value) {
71         return value.map(v -> (State) new DecimalType(new BigDecimal(v))).orElse(UnDefType.UNDEF);
72     }
73
74     /**
75      * Converts an {@link Optional} of {@link Integer} to {@link State} representing a temperature.
76      */
77     public static State intToTemperatureState(Optional<Integer> value) {
78         // The Miele 3rd Party API always provides temperatures in °C (even if the device uses another unit).
79         return value.map(v -> (State) new QuantityType<>(v, SIUnits.CELSIUS)).orElse(UnDefType.UNDEF);
80     }
81
82     /**
83      * Converts an {@link Optional} of {@link Quantity} to {@link State}.
84      */
85     public static State quantityToState(Optional<Quantity> value) {
86         return value.flatMap(ChannelTypeUtil::formatQuantity).flatMap(ChannelTypeUtil::parseQuantityType)
87                 .orElse(UnDefType.UNDEF);
88     }
89
90     /**
91      * Formats the quantity as "value unit" with the given locale.
92      *
93      * @param locale The locale to format with.
94      * @return An {@link Optional} containing the formatted quantity value or an empty {@link Optional} if formatting
95      *         for the given locale failed.
96      */
97     private static Optional<String> formatQuantity(Quantity quantity) {
98         double value = quantity.getValue();
99         try {
100             var formatted = NumberFormat.getInstance(Locale.ENGLISH).format(value);
101
102             var unit = quantity.getUnit();
103             if (unit.isPresent()) {
104                 formatted = formatted + " " + unit.get();
105             }
106
107             return Optional.of(formatted);
108         } catch (ArithmeticException e) {
109             LOGGER.warn("Failed to format {}", value, e);
110             return Optional.empty();
111         }
112     }
113
114     /**
115      * Parses a previously formatted {@link Quantity} into a {@link State}.
116      * 
117      * @param value The quantity value formatted as "value unit".
118      * @return An {@link Optional} containing the parsed {@link State} or an empty {@link Optional} if the quantity
119      *         including unit could not be parsed.
120      */
121     private static Optional<State> parseQuantityType(String value) {
122         try {
123             return Optional.of((State) new QuantityType<>(value));
124         } catch (IllegalArgumentException e) {
125             LOGGER.warn("Failed to convert {} to quantity: {}", value, e.getMessage(), e);
126             return Optional.empty();
127         }
128     }
129 }