]> git.basschouten.com Git - openhab-addons.git/blob
a19612f9155a0baf1ed18dc587140ec3dc963de1
[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.homematic.internal.model;
14
15 import java.util.ArrayList;
16 import java.util.HashMap;
17 import java.util.Iterator;
18 import java.util.List;
19 import java.util.Map;
20
21 import org.openhab.binding.homematic.internal.misc.HomematicConstants;
22
23 /**
24  * Object that represents a Homematic channel.
25  *
26  * @author Gerhard Riegler - Initial contribution
27  */
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";
32
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;
36
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<>();
43
44     public HmChannel(String type, Integer number) {
45         this.type = type;
46         this.number = number;
47     }
48
49     /**
50      * Returns the channel number.
51      */
52     public Integer getNumber() {
53         return number;
54     }
55
56     /**
57      * Returns the device of the channel.
58      */
59     public HmDevice getDevice() {
60         return device;
61     }
62
63     /**
64      * Sets the device of the channel.
65      */
66     public void setDevice(HmDevice device) {
67         this.device = device;
68     }
69
70     /**
71      * Sets the type of the channel.
72      */
73     public String getType() {
74         return type;
75     }
76
77     /**
78      * Sets the flag, if the values for all datapoints has been loaded.
79      *
80      * @param initialized
81      */
82     public void setInitialized(boolean initialized) {
83         this.initialized = initialized;
84     }
85
86     /**
87      * Returns true, if the values for all datapoints has been loaded.
88      */
89     public boolean isInitialized() {
90         return initialized;
91     }
92
93     /**
94      * Returns true, if the channel contains gateway scripts.
95      */
96     public boolean isGatewayScript() {
97         return device.isGatewayExtras() && TYPE_GATEWAY_SCRIPT.equals(type);
98     }
99
100     /**
101      * Returns true, if the channel contains gateway variables.
102      */
103     public boolean isGatewayVariable() {
104         return device.isGatewayExtras() && TYPE_GATEWAY_VARIABLE.equals(type);
105     }
106
107     /**
108      * Returns all datapoints.
109      */
110     public List<HmDatapoint> getDatapoints() {
111         synchronized (datapoints) {
112             return new ArrayList<>(datapoints.values());
113         }
114     }
115
116     /**
117      * Adds a datapoint to the channel.
118      */
119     public void addDatapoint(HmDatapoint dp) {
120         dp.setChannel(this);
121         synchronized (datapoints) {
122             datapoints.put(new HmDatapointInfo(dp), dp);
123         }
124     }
125
126     /**
127      * Removes all datapoints with VALUES param set type from the channel.
128      */
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) {
134                     iterator.remove();
135                 }
136             }
137         }
138     }
139
140     /**
141      * Returns the HmDatapoint with the given HmDatapointInfo.
142      */
143     public HmDatapoint getDatapoint(HmDatapointInfo dpInfo) {
144         synchronized (datapoints) {
145             return datapoints.get(dpInfo);
146         }
147     }
148
149     /**
150      * Returns the HmDatapoint with the given datapoint name.
151      */
152     public HmDatapoint getDatapoint(HmParamsetType type, String datapointName) {
153         return getDatapoint(new HmDatapointInfo(type, this, datapointName));
154     }
155
156     /**
157      * Returns true, if the channel has the given datapoint.
158      */
159     public boolean hasDatapoint(HmDatapointInfo dpInfo) {
160         return getDatapoint(dpInfo) != null;
161     }
162
163     /**
164      * Returns true, if the channel's datapoint set contains a
165      * channel function datapoint.
166      */
167     public boolean isReconfigurable() {
168         return getDatapoint(HmParamsetType.MASTER, HomematicConstants.DATAPOINT_NAME_CHANNEL_FUNCTION) != null;
169     }
170
171     /**
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.
174      */
175     public Integer getCurrentFunction() {
176         HmDatapoint functionDp = getDatapoint(HmParamsetType.MASTER,
177                 HomematicConstants.DATAPOINT_NAME_CHANNEL_FUNCTION);
178         return functionDp == null ? null : (Integer) functionDp.getValue();
179     }
180
181     /**
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.
184      */
185     public synchronized boolean checkForChannelFunctionChange() {
186         Integer currentFunction = getCurrentFunction();
187         if (currentFunction == null) {
188             return false;
189         }
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;
194             return false;
195         }
196         if (lastFunction.equals(currentFunction)) {
197             return false;
198         }
199         lastFunction = currentFunction;
200         return true;
201     }
202
203     /**
204      * Returns true, if the channel has at least one PRESS_ datapoint.
205      */
206     public boolean hasPressDatapoint() {
207         for (HmDatapoint dp : getDatapoints()) {
208             if (dp.isPressDatapoint()) {
209                 return true;
210             }
211         }
212         return false;
213     }
214
215     @Override
216     public String toString() {
217         return String.format("%s[number=%d,initialized=%b]", getClass().getSimpleName(), number, initialized);
218     }
219 }