2 * Copyright (c) 2010-2022 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
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
11 * SPDX-License-Identifier: EPL-2.0
14 package org.openhab.binding.shelly.internal.util;
16 import static org.openhab.binding.shelly.internal.util.ShellyUtils.mkChannelId;
19 import java.util.concurrent.ConcurrentHashMap;
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;
29 * The {@link ShellyChannelCache} implements a caching layer for channel updates.
31 * @author Markus Michels - Initial contribution
34 public class ShellyChannelCache {
35 private final Logger logger = LoggerFactory.getLogger(ShellyChannelCache.class);
37 private final ShellyBaseHandler thingHandler;
38 private final Map<String, State> channelData = new ConcurrentHashMap<>();
39 private String thingName = "";
40 private boolean enabled = false;
42 public ShellyChannelCache(ShellyBaseHandler thingHandler) {
43 this.thingHandler = thingHandler;
44 setThingName(thingHandler.thingName);
47 public void setThingName(String thingName) {
48 this.thingName = thingName;
51 public boolean isEnabled() {
55 public void enable() {
59 public synchronized void disable() {
65 * Update one channel. Use Channel Cache to avoid unnecessary updates (and avoid
66 * messing up the log with those updates)
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
73 public boolean updateChannel(String channelId, State newValue, Boolean forceUpdate) {
76 if (channelData.containsKey(channelId)) {
77 current = channelData.get(channelId);
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
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);
89 channelData.replace(channelId, newValue);
91 logger.debug("{}: Channel {} updated with {} (type {}).", thingName, channelId, newValue,
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);
102 public boolean updateChannel(String group, String channel, State value) {
103 return updateChannel(mkChannelId(group, channel), value, false);
106 public boolean updateChannel(String channelId, State value) {
107 return updateChannel(channelId, value, false);
111 * Get a value from the Channel Cache
113 * @param group Channel Group
114 * @param channel Channel Name
115 * @return the data from that channel
118 public State getValue(String group, String channel) {
119 return getValue(mkChannelId(group, channel));
122 public State getValue(String channelId) {
123 State st = channelData.get(channelId);
124 return st != null ? st : UnDefType.NULL;
127 public void resetChannel(String channelId) {
128 channelData.remove(channelId);
131 public void clear() {