]> git.basschouten.com Git - openhab-addons.git/blob
de709a3b2916f17b6f4c09aac8f83bfb7a55ac6f
[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.anel.internal.state;
14
15 import java.util.Collections;
16 import java.util.HashMap;
17 import java.util.Map;
18 import java.util.function.Function;
19
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.eclipse.jdt.annotation.Nullable;
22 import org.openhab.binding.anel.internal.IAnelConstants;
23 import org.openhab.core.library.types.DecimalType;
24 import org.openhab.core.library.types.OnOffType;
25 import org.openhab.core.library.types.QuantityType;
26 import org.openhab.core.library.types.StringType;
27 import org.openhab.core.library.unit.SIUnits;
28 import org.openhab.core.types.State;
29 import org.openhab.core.types.UnDefType;
30
31 /**
32  * Get updates for {@link AnelState}s.
33  *
34  * @author Patrick Koenemann - Initial contribution
35  */
36 @NonNullByDefault
37 public class AnelStateUpdater {
38
39     public @Nullable State getChannelUpdate(String channelId, @Nullable AnelState state) {
40         if (state == null) {
41             return null;
42         }
43
44         final int index = IAnelConstants.getIndexFromChannel(channelId);
45         if (index >= 0) {
46             if (IAnelConstants.CHANNEL_RELAY_NAME.contains(channelId)) {
47                 return getStringState(state.relayName[index]);
48             }
49             if (IAnelConstants.CHANNEL_RELAY_STATE.contains(channelId)) {
50                 return getSwitchState(state.relayState[index]);
51             }
52             if (IAnelConstants.CHANNEL_RELAY_LOCKED.contains(channelId)) {
53                 return getSwitchState(state.relayLocked[index]);
54             }
55
56             if (IAnelConstants.CHANNEL_IO_NAME.contains(channelId)) {
57                 return getStringState(state.ioName[index]);
58             }
59             if (IAnelConstants.CHANNEL_IO_STATE.contains(channelId)) {
60                 return getSwitchState(state.ioState[index]);
61             }
62             if (IAnelConstants.CHANNEL_IO_MODE.contains(channelId)) {
63                 return getSwitchState(state.ioState[index]);
64             }
65         } else {
66             if (IAnelConstants.CHANNEL_NAME.equals(channelId)) {
67                 return getStringState(state.name);
68             }
69             if (IAnelConstants.CHANNEL_TEMPERATURE.equals(channelId)) {
70                 return getTemperatureState(state.temperature);
71             }
72
73             if (IAnelConstants.CHANNEL_SENSOR_TEMPERATURE.equals(channelId)) {
74                 return getTemperatureState(state.sensorTemperature);
75             }
76             if (IAnelConstants.CHANNEL_SENSOR_HUMIDITY.equals(channelId)) {
77                 return getDecimalState(state.sensorHumidity);
78             }
79             if (IAnelConstants.CHANNEL_SENSOR_BRIGHTNESS.equals(channelId)) {
80                 return getDecimalState(state.sensorBrightness);
81             }
82         }
83         return null;
84     }
85
86     public Map<String, State> getChannelUpdates(@Nullable AnelState oldState, AnelState newState) {
87         if (oldState != null && newState.status.equals(oldState.status)) {
88             return Collections.emptyMap(); // definitely no change!
89         }
90
91         final Map<String, State> updates = new HashMap<>();
92
93         // name and device temperature
94         final State newName = getNewStringState(oldState == null ? null : oldState.name, newState.name);
95         if (newName != null) {
96             updates.put(IAnelConstants.CHANNEL_NAME, newName);
97         }
98         final State newTemperature = getNewTemperatureState(oldState == null ? null : oldState.temperature,
99                 newState.temperature);
100         if (newTemperature != null) {
101             updates.put(IAnelConstants.CHANNEL_TEMPERATURE, newTemperature);
102         }
103
104         // relay properties
105         for (int i = 0; i < 8; i++) {
106             final State newRelayName = getNewStringState(oldState == null ? null : oldState.relayName[i],
107                     newState.relayName[i]);
108             if (newRelayName != null) {
109                 updates.put(IAnelConstants.CHANNEL_RELAY_NAME.get(i), newRelayName);
110             }
111
112             final State newRelayState = getNewSwitchState(oldState == null ? null : oldState.relayState[i],
113                     newState.relayState[i]);
114             if (newRelayState != null) {
115                 updates.put(IAnelConstants.CHANNEL_RELAY_STATE.get(i), newRelayState);
116             }
117
118             final State newRelayLocked = getNewSwitchState(oldState == null ? null : oldState.relayLocked[i],
119                     newState.relayLocked[i]);
120             if (newRelayLocked != null) {
121                 updates.put(IAnelConstants.CHANNEL_RELAY_LOCKED.get(i), newRelayLocked);
122             }
123         }
124
125         // IO properties
126         for (int i = 0; i < 8; i++) {
127             final State newIOName = getNewStringState(oldState == null ? null : oldState.ioName[i], newState.ioName[i]);
128             if (newIOName != null) {
129                 updates.put(IAnelConstants.CHANNEL_IO_NAME.get(i), newIOName);
130             }
131
132             final State newIOIsInput = getNewSwitchState(oldState == null ? null : oldState.ioIsInput[i],
133                     newState.ioIsInput[i]);
134             if (newIOIsInput != null) {
135                 updates.put(IAnelConstants.CHANNEL_IO_MODE.get(i), newIOIsInput);
136             }
137
138             final State newIOState = getNewSwitchState(oldState == null ? null : oldState.ioState[i],
139                     newState.ioState[i]);
140             if (newIOState != null) {
141                 updates.put(IAnelConstants.CHANNEL_IO_STATE.get(i), newIOState);
142             }
143         }
144
145         // sensor values
146         final State newSensorTemperature = getNewTemperatureState(oldState == null ? null : oldState.sensorTemperature,
147                 newState.sensorTemperature);
148         if (newSensorTemperature != null) {
149             updates.put(IAnelConstants.CHANNEL_SENSOR_TEMPERATURE, newSensorTemperature);
150         }
151         final State newSensorHumidity = getNewDecimalState(oldState == null ? null : oldState.sensorHumidity,
152                 newState.sensorHumidity);
153         if (newSensorHumidity != null) {
154             updates.put(IAnelConstants.CHANNEL_SENSOR_HUMIDITY, newSensorHumidity);
155         }
156         final State newSensorBrightness = getNewDecimalState(oldState == null ? null : oldState.sensorBrightness,
157                 newState.sensorBrightness);
158         if (newSensorBrightness != null) {
159             updates.put(IAnelConstants.CHANNEL_SENSOR_BRIGHTNESS, newSensorBrightness);
160         }
161
162         return updates;
163     }
164
165     private @Nullable State getStringState(@Nullable String value) {
166         return value == null ? null : new StringType(value);
167     }
168
169     private @Nullable State getDecimalState(@Nullable String value) {
170         return value == null ? null : new DecimalType(value);
171     }
172
173     private @Nullable State getTemperatureState(@Nullable String value) {
174         if (value == null || value.trim().isEmpty()) {
175             return null;
176         }
177         final float floatValue = Float.parseFloat(value);
178         return QuantityType.valueOf(floatValue, SIUnits.CELSIUS);
179     }
180
181     private @Nullable State getSwitchState(@Nullable Boolean value) {
182         return value == null ? null : OnOffType.from(value.booleanValue());
183     }
184
185     private @Nullable State getNewStringState(@Nullable String oldValue, @Nullable String newValue) {
186         return getNewState(oldValue, newValue, StringType::new);
187     }
188
189     private @Nullable State getNewDecimalState(@Nullable String oldValue, @Nullable String newValue) {
190         return getNewState(oldValue, newValue, DecimalType::new);
191     }
192
193     private @Nullable State getNewTemperatureState(@Nullable String oldValue, @Nullable String newValue) {
194         return getNewState(oldValue, newValue, value -> QuantityType.valueOf(Float.parseFloat(value), SIUnits.CELSIUS));
195     }
196
197     private @Nullable State getNewSwitchState(@Nullable Boolean oldValue, @Nullable Boolean newValue) {
198         return getNewState(oldValue, newValue, value -> OnOffType.from(value.booleanValue()));
199     }
200
201     private <T> @Nullable State getNewState(@Nullable T oldValue, @Nullable T newValue,
202             Function<T, State> createState) {
203         if (oldValue == null) {
204             if (newValue == null) {
205                 return null; // no change
206             } else {
207                 return createState.apply(newValue); // from null to some value
208             }
209         } else if (newValue == null) {
210             return UnDefType.NULL; // from some value to null
211         } else if (oldValue.equals(newValue)) {
212             return null; // no change
213         }
214         return createState.apply(newValue); // from some value to another value
215     }
216 }