2 * Copyright (c) 2010-2023 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
13 package org.openhab.binding.homematic.internal.model;
15 import java.util.ArrayList;
16 import java.util.HashMap;
17 import java.util.Iterator;
18 import java.util.List;
21 import org.openhab.binding.homematic.internal.misc.HomematicConstants;
24 * Object that represents a Homematic channel.
26 * @author Gerhard Riegler - Initial contribution
28 public class HmChannel {
29 public static final String TYPE_GATEWAY_EXTRAS = "GATEWAY-EXTRAS";
30 public static final String TYPE_GATEWAY_VARIABLE = "GATEWAY-VARIABLE";
31 public static final String TYPE_GATEWAY_SCRIPT = "GATEWAY-SCRIPT";
33 public static final Integer CHANNEL_NUMBER_EXTRAS = 0;
34 public static final Integer CHANNEL_NUMBER_VARIABLE = 1;
35 public static final Integer CHANNEL_NUMBER_SCRIPT = 2;
37 private final Integer number;
38 private final String type;
39 private HmDevice device;
40 private boolean initialized;
41 private Integer lastFunction;
42 private Map<HmDatapointInfo, HmDatapoint> datapoints = new HashMap<>();
44 public HmChannel(String type, Integer number) {
50 * Returns the channel number.
52 public Integer getNumber() {
57 * Returns the device of the channel.
59 public HmDevice getDevice() {
64 * Sets the device of the channel.
66 public void setDevice(HmDevice device) {
71 * Sets the type of the channel.
73 public String getType() {
78 * Sets the flag, if the values for all datapoints has been loaded.
82 public void setInitialized(boolean initialized) {
83 this.initialized = initialized;
87 * Returns true, if the values for all datapoints has been loaded.
89 public boolean isInitialized() {
94 * Returns true, if the channel contains gateway scripts.
96 public boolean isGatewayScript() {
97 return device.isGatewayExtras() && TYPE_GATEWAY_SCRIPT.equals(type);
101 * Returns true, if the channel contains gateway variables.
103 public boolean isGatewayVariable() {
104 return device.isGatewayExtras() && TYPE_GATEWAY_VARIABLE.equals(type);
108 * Returns all datapoints.
110 public List<HmDatapoint> getDatapoints() {
111 synchronized (datapoints) {
112 return new ArrayList<>(datapoints.values());
117 * Adds a datapoint to the channel.
119 public void addDatapoint(HmDatapoint dp) {
121 synchronized (datapoints) {
122 datapoints.put(new HmDatapointInfo(dp), dp);
127 * Removes all datapoints with VALUES param set type from the channel.
129 public void removeValueDatapoints() {
130 synchronized (datapoints) {
131 Iterator<Map.Entry<HmDatapointInfo, HmDatapoint>> iterator = datapoints.entrySet().iterator();
132 while (iterator.hasNext()) {
133 if (iterator.next().getKey().getParamsetType() == HmParamsetType.VALUES) {
141 * Returns the HmDatapoint with the given HmDatapointInfo.
143 public HmDatapoint getDatapoint(HmDatapointInfo dpInfo) {
144 synchronized (datapoints) {
145 return datapoints.get(dpInfo);
150 * Returns the HmDatapoint with the given datapoint name.
152 public HmDatapoint getDatapoint(HmParamsetType type, String datapointName) {
153 return getDatapoint(new HmDatapointInfo(type, this, datapointName));
157 * Returns true, if the channel has the given datapoint.
159 public boolean hasDatapoint(HmDatapointInfo dpInfo) {
160 return getDatapoint(dpInfo) != null;
164 * Returns true, if the channel's datapoint set contains a
165 * channel function datapoint.
167 public boolean isReconfigurable() {
168 return getDatapoint(HmParamsetType.MASTER, HomematicConstants.DATAPOINT_NAME_CHANNEL_FUNCTION) != null;
172 * Returns the numeric value of the function this channel is currently configured to.
173 * Returns null if the channel is not yet initialized or does not support dynamic reconfiguration.
175 public Integer getCurrentFunction() {
176 HmDatapoint functionDp = getDatapoint(HmParamsetType.MASTER,
177 HomematicConstants.DATAPOINT_NAME_CHANNEL_FUNCTION);
178 return functionDp == null ? null : (Integer) functionDp.getValue();
182 * Checks whether the function this channel is configured to changed since this method was last invoked.
183 * Returns false if the channel is not reconfigurable or was not initialized yet.
185 public synchronized boolean checkForChannelFunctionChange() {
186 Integer currentFunction = getCurrentFunction();
187 if (currentFunction == null) {
190 if (lastFunction == null) {
191 // We were called from initialization, which was preceded by initial metadata fetch, so everything
192 // should be fine by now
193 lastFunction = currentFunction;
196 if (lastFunction.equals(currentFunction)) {
199 lastFunction = currentFunction;
204 * Returns true, if the channel has at least one PRESS_ datapoint.
206 public boolean hasPressDatapoint() {
207 for (HmDatapoint dp : getDatapoints()) {
208 if (dp.isPressDatapoint()) {
216 public String toString() {
217 return String.format("%s[number=%d,initialized=%b]", getClass().getSimpleName(), number, initialized);