]> git.basschouten.com Git - openhab-addons.git/blob
a0340467a1eab50d531edd775d7bceb019baad7b
[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.velux.internal.bridge;
14
15 import org.eclipse.jdt.annotation.NonNullByDefault;
16 import org.openhab.binding.velux.internal.bridge.common.GetProduct;
17 import org.openhab.binding.velux.internal.bridge.common.GetProducts;
18 import org.openhab.binding.velux.internal.things.VeluxExistingProducts;
19 import org.openhab.binding.velux.internal.things.VeluxKLFAPI;
20 import org.openhab.binding.velux.internal.things.VeluxProduct;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
23
24 /**
25  * The {@link VeluxBridgeActuators} represents a complete set of transactions
26  * for retrieving of any available products into a structure {@link #channel}
27  * defined on the <B>Velux</B> bridge.
28  * <P>
29  * It provides the methods:
30  * <UL>
31  * <LI>{@link #getProducts} for retrieval of information from the bridge.
32  * <LI>{@link #getChannel} for accessing the retrieved information.
33  * <LI>{@link #autoRefresh} for retrieval of information for supporting the update the corresponding openHAB items.
34  * </UL>
35  *
36  * @see VeluxProduct
37  * @see VeluxExistingProducts
38  * @see VeluxBridgeProvider
39  *
40  * @author Guenther Schreiner - Initial contribution
41  */
42 @NonNullByDefault
43 public class VeluxBridgeActuators {
44     private final Logger logger = LoggerFactory.getLogger(VeluxBridgeActuators.class);
45
46     // Configuration constants
47
48     /**
49      * Limitation of Discovery on parts of the System table
50      *
51      * Whereas the parameter {@link org.openhab.binding.velux.internal.things.VeluxKLFAPI#KLF_SYSTEMTABLE_MAX}
52      * represents the
53      * maximum size of the system table in general, for speed up of the discovery process
54      * a binding-internal limitation of number of possible devices is introduced.
55      */
56     private static final int VELUXBINDING_SYSTEMTABLE_MAX = 16;
57
58     // Type definitions, class-internal variables
59
60     /**
61      * Actuator information consisting of:
62      * <ul>
63      * <li>isRetrieved (boolean),
64      * <li>existingProducts ({@link VeluxExistingProducts}).
65      * </ul>
66      */
67     public class Channel {
68         public VeluxExistingProducts existingProducts = new VeluxExistingProducts();
69     }
70
71     private Channel channel;
72
73     // Constructor methods
74
75     /**
76      * Constructor.
77      * <P>
78      * Initializes the internal data structure {@link #channel} of Velux actuators/products,
79      * which is publicly accessible via the method {@link #getChannel()}.
80      */
81     public VeluxBridgeActuators() {
82         logger.trace("VeluxBridgeActuators(constructor) called.");
83         channel = new Channel();
84         logger.trace("VeluxBridgeActuators(constructor) done.");
85     }
86
87     // Class access methods
88
89     /**
90      * Provide access to the internal structure of actuators/products.
91      *
92      * @return a channel describing the overall actuator situation.
93      */
94     public Channel getChannel() {
95         return channel;
96     }
97
98     /**
99      * Login into bridge, retrieve all products and logout from bridge based
100      * on a well-prepared environment of a {@link VeluxBridgeProvider}. The results
101      * are stored within {@link org.openhab.binding.velux.internal.things.VeluxExistingProducts
102      * VeluxExistingProducts}.
103      *
104      * @param bridge Initialized Velux bridge (communication) handler.
105      * @return true if successful, and false otherwise.
106      */
107     public boolean getProducts(VeluxBridge bridge) {
108         logger.trace("getProducts() called.");
109
110         GetProducts bcp = bridge.bridgeAPI().getProducts();
111         GetProduct bcpSbS = bridge.bridgeAPI().getProduct();
112         if ((bcpSbS != null) && !bridge.bridgeInstance.veluxBridgeConfiguration().isBulkRetrievalEnabled) {
113             logger.trace("getProducts() working on step-by-step retrieval.");
114             for (int nodeId = 0; nodeId < VeluxKLFAPI.KLF_SYSTEMTABLE_MAX
115                     && nodeId < VELUXBINDING_SYSTEMTABLE_MAX; nodeId++) {
116                 logger.trace("getProducts() working on product number {}.", nodeId);
117                 bcpSbS.setProductId(nodeId);
118                 if (bridge.bridgeCommunicate(bcpSbS) && bcpSbS.isCommunicationSuccessful()) {
119                     VeluxProduct veluxProduct = bcpSbS.getProduct();
120                     if (bcpSbS.isCommunicationSuccessful()) {
121                         logger.debug("getProducts() found product {}.", veluxProduct);
122                         if (!channel.existingProducts.isRegistered(veluxProduct)) {
123                             channel.existingProducts.register(veluxProduct);
124                         }
125                     }
126                 }
127             }
128         } else {
129             logger.trace("getProducts() working on bulk retrieval.");
130             if (bridge.bridgeCommunicate(bcp) && bcp.isCommunicationSuccessful()) {
131                 for (VeluxProduct product : bcp.getProducts()) {
132                     logger.trace("getProducts() found product {} (type {}).", product.getProductName(),
133                             product.getProductType());
134                     if (!channel.existingProducts.isRegistered(product)) {
135                         logger.debug("getProducts() storing new product {}.", product);
136                         channel.existingProducts.register(product);
137                     } else {
138                         logger.debug("getProducts() storing updates for product {}.", product);
139                         channel.existingProducts.update(product);
140                     }
141                 }
142             } else {
143                 logger.trace("getProducts() finished with failure.");
144                 return false;
145             }
146         }
147         logger.debug("getProducts() finally has found products {}.", channel.existingProducts);
148         return true;
149     }
150
151     /**
152      * In case of an empty list of recognized products, the method will
153      * initiate a product retrieval using {@link #getProducts(VeluxBridge)}.
154      *
155      * @param bridge Initialized Velux bridge (communication) handler.
156      * @return true if at least one product was found, and false otherwise.
157      */
158     public boolean autoRefresh(VeluxBridge bridge) {
159         int numberOfActuators = channel.existingProducts.getNoMembers();
160         if (numberOfActuators == 0) {
161             logger.trace("autoRefresh(): is about to fetch existing products.");
162             getProducts(bridge);
163         }
164         return (numberOfActuators > 0);
165     }
166 }