]> git.basschouten.com Git - openhab-addons.git/blob
8e197292c634522405006abf29be4605e66173cb
[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.nibeuplink.internal.model;
14
15 import static org.openhab.binding.nibeuplink.internal.NibeUplinkBindingConstants.*;
16
17 import java.util.HashMap;
18 import java.util.Map;
19
20 import javax.measure.Unit;
21
22 import org.eclipse.jdt.annotation.NonNullByDefault;
23 import org.openhab.binding.nibeuplink.internal.handler.ChannelProvider;
24 import org.openhab.binding.nibeuplink.internal.handler.ChannelUtil;
25 import org.openhab.core.library.types.DecimalType;
26 import org.openhab.core.library.types.QuantityType;
27 import org.openhab.core.library.unit.MetricPrefix;
28 import org.openhab.core.library.unit.SIUnits;
29 import org.openhab.core.library.unit.Units;
30 import org.openhab.core.thing.Channel;
31 import org.openhab.core.thing.type.ChannelTypeUID;
32 import org.openhab.core.types.State;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36 /**
37  * transforms the http response into the openhab datamodel (instances of State)
38  *
39  * @author Alexander Friese - initial contribution
40  */
41 @NonNullByDefault
42 public class DataResponseTransformer {
43     private final Logger logger = LoggerFactory.getLogger(DataResponseTransformer.class);
44
45     private static final double UNSCALED = 1;
46     private static final double DIV_10 = 0.1;
47     private static final double DIV_100 = 0.01;
48
49     private final ChannelProvider channelProvider;
50
51     public DataResponseTransformer(ChannelProvider channelProvider) {
52         this.channelProvider = channelProvider;
53     }
54
55     public Map<Channel, State> transform(DataResponse response) {
56         Map<String, Long> source = response.getValues();
57         Map<Channel, State> result = new HashMap<>(source.size());
58
59         for (String channelId : source.keySet()) {
60             Long value = source.get(channelId);
61
62             Channel channel = channelProvider.getSpecificChannel(channelId);
63             if (channel == null) {
64                 // This should not happen but we want to get informed about it
65                 logger.warn("Channel not found: {}", channelId);
66             } else {
67                 ChannelTypeUID typeUID = channel.getChannelTypeUID();
68                 String type = typeUID == null ? "null" : typeUID.getId();
69
70                 switch (type) {
71                     case CHANNEL_TYPE_TEMPERATURE:
72                     case CHANNEL_TYPE_START_COOLING_RW:
73                         putQuantityType(result, channel, value, DIV_10, SIUnits.CELSIUS);
74                         break;
75                     case CHANNEL_TYPE_PRESSURE:
76                         putQuantityType(result, channel, value, DIV_10, Units.BAR);
77                         break;
78                     case CHANNEL_TYPE_ENERGY:
79                         putQuantityType(result, channel, value, DIV_10, MetricPrefix.KILO(Units.WATT_HOUR));
80                         break;
81                     case CHANNEL_TYPE_POWER:
82                         putQuantityType(result, channel, value, DIV_100, MetricPrefix.KILO(Units.WATT));
83                         break;
84                     case CHANNEL_TYPE_SWITCH_RW:
85                     case CHANNEL_TYPE_SWITCH:
86                         putOnOffType(result, channel, value);
87                         break;
88                     case CHANNEL_TYPE_ELECTRIC_CURRENT:
89                         putQuantityType(result, channel, value, DIV_10, Units.AMPERE);
90                         break;
91                     case CHANNEL_TYPE_TIME_UNSCALED:
92                         putQuantityType(result, channel, value, UNSCALED, Units.HOUR);
93                         break;
94                     case CHANNEL_TYPE_TIME_SCALE10:
95                         putQuantityType(result, channel, value, DIV_10, Units.HOUR);
96                         break;
97                     case CHANNEL_TYPE_FREQUENCY_UNSCALED:
98                         putQuantityType(result, channel, value, UNSCALED, Units.HERTZ);
99                         break;
100                     case CHANNEL_TYPE_FREQUENCY_SCALE10:
101                         putQuantityType(result, channel, value, DIV_10, Units.HERTZ);
102                         break;
103                     case CHANNEL_TYPE_FLOW:
104                         putQuantityType(result, channel, value, DIV_10, Units.LITRE.divide(Units.MINUTE));
105                         break;
106                     case CHANNEL_TYPE_SPEED:
107                         putQuantityType(result, channel, value, UNSCALED, Units.PERCENT);
108                         break;
109                     case CHANNEL_TYPE_NUMBER_SCALE100:
110                         putDecimalType(result, channel, value, DIV_100);
111                         break;
112                     case CHANNEL_TYPE_NUMBER_SCALE10:
113                     case CHANNEL_TYPE_DEGREE_MINUTES_RW:
114                     case CHANNEL_TYPE_STOP_HEATING_RW:
115                     case CHANNEL_TYPE_STOP_ADD_HEATING_RW:
116                     case CHANNEL_TYPE_ROOM_SENSOR_FACTOR_RW:
117                         putDecimalType(result, channel, value, DIV_10);
118                         break;
119                     case CHANNEL_TYPE_NUMBER_UNSCALED:
120                     case CHANNEL_TYPE_DEFROSTING_STATE:
121                     case CHANNEL_TYPE_HPAC_STATE:
122                     case CHANNEL_TYPE_HW_LUX_RW:
123                     case CHANNEL_TYPE_HW_MODE_RW:
124                     case CHANNEL_TYPE_FAN_SPEED_RW:
125                     case CHANNEL_TYPE_FILTER_TIME_RW:
126                     case CHANNEL_TYPE_HEAT_OFFSET_RW:
127                         putDecimalType(result, channel, value, UNSCALED);
128                         break;
129                     default:
130                         logger.warn("could not handle unknown type {}, channel {}, value {}", type, channel.getUID(),
131                                 value);
132                 }
133             }
134         }
135         return result;
136     }
137
138     private final void putQuantityType(Map<Channel, State> targetMap, Channel channel, long value, double factor,
139             Unit<?> unit) {
140         // make sure that values are stored as long if no factor is to be applied
141         State val = factor == UNSCALED ? new QuantityType<>(value, unit) : new QuantityType<>(value * factor, unit);
142         targetMap.put(channel, val);
143         logger.debug("Channel {} transformed to QuantityType ({}*{} {}) -> {}", channel.getUID().getId(), value, factor,
144                 unit, val);
145     }
146
147     private final void putOnOffType(Map<Channel, State> targetMap, Channel channel, long value) {
148         State val = ChannelUtil.mapValue(channel, value);
149         targetMap.put(channel, val);
150         logger.debug("Channel {} transformed to OnOffType ({}) -> {}", channel.getUID().getId(), value, val);
151     }
152
153     private final void putDecimalType(Map<Channel, State> targetMap, Channel channel, long value, double factor) {
154         // make sure that values are stored as long if no factor is to be applied
155         State val = factor == UNSCALED ? new DecimalType(value) : new DecimalType(value * factor);
156         targetMap.put(channel, val);
157         logger.debug("Channel {} transformed to DecimalType ({}*{}) -> {}", channel.getUID().getId(), value, factor,
158                 val);
159     }
160 }