]> git.basschouten.com Git - openhab-addons.git/blob
30cafdef815bed886604aad69c4d737dd193b5da
[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.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.ShellyThingInterface;
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 ShellyThingInterface thingHandler;
37     private final Map<String, State> channelData = new ConcurrentHashMap<>();
38     private String thingName = "";
39     private boolean enabled = false;
40
41     public ShellyChannelCache(ShellyThingInterface thingHandler) {
42         this.thingHandler = thingHandler;
43         setThingName(thingHandler.getThingName());
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 newValue 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.equals(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                 return true;
91             }
92         } catch (IllegalArgumentException e) {
93             logger.debug("{}: Unable to update channel {} with {} (type {}): {} ({})", thingName, channelId, newValue,
94                     newValue.getClass(), ShellyUtils.getMessage(e), e.getClass(), e);
95         }
96         return false;
97     }
98
99     public boolean updateChannel(String group, String channel, State value) {
100         return updateChannel(mkChannelId(group, channel), value, false);
101     }
102
103     public boolean updateChannel(String channelId, State value) {
104         return updateChannel(channelId, value, false);
105     }
106
107     /**
108      * Get a value from the Channel Cache
109      *
110      * @param group Channel Group
111      * @param channel Channel Name
112      * @return the data from that channel
113      */
114
115     public State getValue(String group, String channel) {
116         return getValue(mkChannelId(group, channel));
117     }
118
119     public State getValue(String channelId) {
120         State st = channelData.get(channelId);
121         return st != null ? st : UnDefType.NULL;
122     }
123
124     public void resetChannel(String channelId) {
125         channelData.remove(channelId);
126     }
127
128     public void clear() {
129         channelData.clear();
130     }
131 }