]> git.basschouten.com Git - openhab-addons.git/blob
f9b42823dd2829a197eea848c660b44ddde821cf
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2021 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.shelly.internal.util;
14
15 import static org.openhab.binding.shelly.internal.util.ShellyUtils.mkChannelId;
16
17 import java.util.Map;
18 import java.util.concurrent.ConcurrentHashMap;
19
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.openhab.binding.shelly.internal.handler.ShellyBaseHandler;
22 import org.openhab.core.types.State;
23 import org.openhab.core.types.UnDefType;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26
27 /**
28  * The {@link ShellyChannelCache} implements a caching layer for channel updates.
29  *
30  * @author Markus Michels - Initial contribution
31  */
32 @NonNullByDefault
33 public class ShellyChannelCache {
34     private final Logger logger = LoggerFactory.getLogger(ShellyChannelCache.class);
35
36     private final ShellyBaseHandler thingHandler;
37     private final Map<String, State> channelData = new ConcurrentHashMap<>();
38     private String thingName = "";
39     private boolean enabled = false;
40
41     public ShellyChannelCache(ShellyBaseHandler thingHandler) {
42         this.thingHandler = thingHandler;
43         setThingName(thingHandler.thingName);
44     }
45
46     public void setThingName(String thingName) {
47         this.thingName = thingName;
48     }
49
50     public boolean isEnabled() {
51         return enabled;
52     }
53
54     public void enable() {
55         enabled = true;
56     }
57
58     public synchronized void disable() {
59         clear();
60         enabled = false;
61     }
62
63     /**
64      * Update one channel. Use Channel Cache to avoid unnecessary updates (and avoid
65      * messing up the log with those updates)
66      *
67      * @param channelId Channel id
68      * @param value Value (State)
69      * @param forceUpdate true: ignore cached data, force update; false check cache of changed data
70      * @return true, if successful
71      */
72     public boolean updateChannel(String channelId, State newValue, Boolean forceUpdate) {
73         try {
74             State current = null;
75             if (channelData.containsKey(channelId)) {
76                 current = channelData.get(channelId);
77             }
78             if (!enabled || forceUpdate || (current == null) || !current.equals(newValue)) {
79                 if ((current != null) && current.getClass().isEnum() && (current == newValue)) {
80                     return false; // special case for OnOffType
81                 }
82                 // For channels that support multiple types (like brightness) a suffix is added
83                 // this gets removed to get the channelId for updateState
84                 thingHandler.publishState(channelId, newValue);
85                 if (current == null) {
86                     channelData.put(channelId, newValue);
87                 } else {
88                     channelData.replace(channelId, newValue);
89                 }
90                 logger.debug("{}: Channel {} updated with {} (type {}).", thingName, channelId, newValue,
91                         newValue.getClass());
92                 return true;
93             }
94         } catch (IllegalArgumentException e) {
95             logger.debug("{}: Unable to update channel {} with {} (type {}): {} ({})", thingName, channelId, newValue,
96                     newValue.getClass(), ShellyUtils.getMessage(e), e.getClass());
97         }
98         return false;
99     }
100
101     public boolean updateChannel(String group, String channel, State value) {
102         return updateChannel(mkChannelId(group, channel), value, false);
103     }
104
105     public boolean updateChannel(String channelId, State value) {
106         return updateChannel(channelId, value, false);
107     }
108
109     /**
110      * Get a value from the Channel Cache
111      *
112      * @param group Channel Group
113      * @param channel Channel Name
114      * @return the data from that channel
115      */
116
117     public State getValue(String group, String channel) {
118         return getValue(mkChannelId(group, channel));
119     }
120
121     public State getValue(String channelId) {
122         return channelData.getOrDefault(channelId, UnDefType.NULL);
123     }
124
125     public void resetChannel(String channelId) {
126         channelData.remove(channelId);
127     }
128
129     public void clear() {
130         channelData.clear();
131     }
132 }