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