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.dbquery.internal;
15 import java.math.BigDecimal;
16 import java.math.BigInteger;
17 import java.time.Duration;
18 import java.time.Instant;
19 import java.time.ZoneId;
20 import java.time.ZonedDateTime;
21 import java.util.Base64;
22 import java.util.Date;
24 import org.eclipse.jdt.annotation.NonNullByDefault;
25 import org.eclipse.jdt.annotation.Nullable;
26 import org.openhab.binding.dbquery.internal.domain.DBQueryJSONEncoder;
27 import org.openhab.binding.dbquery.internal.domain.QueryResult;
28 import org.openhab.binding.dbquery.internal.error.UnnexpectedCondition;
29 import org.openhab.core.library.types.DateTimeType;
30 import org.openhab.core.library.types.DecimalType;
31 import org.openhab.core.library.types.OnOffType;
32 import org.openhab.core.library.types.OpenClosedType;
33 import org.openhab.core.library.types.StringType;
34 import org.openhab.core.types.State;
35 import org.openhab.core.types.UnDefType;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
40 * Manage conversion from a value to needed State target type
42 * @author Joan Pujol - Initial contribution
45 public class Value2StateConverter {
46 private final Logger logger = LoggerFactory.getLogger(Value2StateConverter.class);
47 private final DBQueryJSONEncoder jsonEncoder = new DBQueryJSONEncoder();
49 public State convertValue(@Nullable Object value, Class<? extends State> targetType) {
51 return UnDefType.NULL;
53 if (targetType == StringType.class) {
54 return convert2String(value);
55 } else if (targetType == DecimalType.class) {
56 return convert2Decimal(value);
57 } else if (targetType == DateTimeType.class) {
58 return convert2DateTime(value);
59 } else if (targetType == OnOffType.class) {
61 Boolean bool = convert2Boolean(value);
62 return bool != null ? OnOffType.from(bool) : UnDefType.NULL;
63 } else if (targetType == OpenClosedType.class) {
65 Boolean bool = convert2Boolean(value);
67 return bool ? OpenClosedType.OPEN : OpenClosedType.CLOSED;
69 return UnDefType.NULL;
72 throw new UnnexpectedCondition("Not expected targetType " + targetType);
77 private State convert2DateTime(Object value) {
78 if (value instanceof Instant) {
79 return new DateTimeType(ZonedDateTime.ofInstant((Instant) value, ZoneId.systemDefault()));
80 } else if (value instanceof Date) {
81 return new DateTimeType(ZonedDateTime.ofInstant(((Date) value).toInstant(), ZoneId.systemDefault()));
82 } else if (value instanceof String) {
83 return new DateTimeType((String) value);
85 logger.warn("Can't convert {} to DateTimeType", value);
86 return UnDefType.NULL;
90 private State convert2Decimal(Object value) {
91 if (value instanceof Integer) {
92 return new DecimalType((Integer) value);
93 } else if (value instanceof Long) {
94 return new DecimalType((Long) value);
95 } else if (value instanceof Float) {
96 return new DecimalType((Float) value);
97 } else if (value instanceof Double) {
98 return new DecimalType((Double) value);
99 } else if (value instanceof BigDecimal) {
100 return new DecimalType((BigDecimal) value);
101 } else if (value instanceof BigInteger) {
102 return new DecimalType(new BigDecimal((BigInteger) value));
103 } else if (value instanceof Number) {
104 return new DecimalType(((Number) value).longValue());
105 } else if (value instanceof String) {
106 return DecimalType.valueOf((String) value);
107 } else if (value instanceof Duration) {
108 return new DecimalType(((Duration) value).toMillis());
110 logger.warn("Can't convert {} to DecimalType", value);
111 return UnDefType.NULL;
115 private State convert2String(Object value) {
116 if (value instanceof String) {
117 return new StringType((String) value);
118 } else if (value instanceof byte[]) {
119 return new StringType(Base64.getEncoder().encodeToString((byte[]) value));
120 } else if (value instanceof QueryResult) {
121 return new StringType(jsonEncoder.encode((QueryResult) value));
123 return new StringType(String.valueOf(value));
127 private @Nullable Boolean convert2Boolean(Object value) {
128 if (value instanceof Boolean) {
129 return (Boolean) value;
130 } else if (value instanceof Number) {
131 return ((Number) value).doubleValue() != 0d;
132 } else if (value instanceof String) {
133 var svalue = (String) value;
134 return Boolean.parseBoolean(svalue) || (svalue.equalsIgnoreCase("on")) || svalue.equals("1");
136 logger.warn("Can't convert {} to OnOffType or OpenClosedType", value);