]> git.basschouten.com Git - openhab-addons.git/blob
b09ddbf56844ea8248fb3a7ef3576ddfecec9fa2
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 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     @NonNullByDefault
68     public class Channel {
69         public VeluxExistingProducts existingProducts = new VeluxExistingProducts();
70     }
71
72     private Channel channel;
73
74     // Constructor methods
75
76     /**
77      * Constructor.
78      * <P>
79      * Initializes the internal data structure {@link #channel} of Velux actuators/products,
80      * which is publicly accessible via the method {@link #getChannel()}.
81      */
82     public VeluxBridgeActuators() {
83         logger.trace("VeluxBridgeActuators(constructor) called.");
84         channel = new Channel();
85         logger.trace("VeluxBridgeActuators(constructor) done.");
86     }
87
88     // Class access methods
89
90     /**
91      * Provide access to the internal structure of actuators/products.
92      *
93      * @return a channel describing the overall actuator situation.
94      */
95     public Channel getChannel() {
96         return channel;
97     }
98
99     /**
100      * Login into bridge, retrieve all products and logout from bridge based
101      * on a well-prepared environment of a {@link VeluxBridgeProvider}. The results
102      * are stored within {@link org.openhab.binding.velux.internal.things.VeluxExistingProducts
103      * VeluxExistingProducts}.
104      *
105      * @param bridge Initialized Velux bridge (communication) handler.
106      * @return true if successful, and false otherwise.
107      */
108     public boolean getProducts(VeluxBridge bridge) {
109         logger.trace("getProducts() called.");
110
111         GetProducts bcp = bridge.bridgeAPI().getProducts();
112         GetProduct bcpSbS = bridge.bridgeAPI().getProduct();
113         if ((bcpSbS != null) && !bridge.bridgeInstance.veluxBridgeConfiguration().isBulkRetrievalEnabled) {
114             logger.trace("getProducts() working on step-by-step retrieval.");
115             for (int nodeId = 0; nodeId < VeluxKLFAPI.KLF_SYSTEMTABLE_MAX
116                     && nodeId < VELUXBINDING_SYSTEMTABLE_MAX; nodeId++) {
117                 logger.trace("getProducts() working on product number {}.", nodeId);
118                 bcpSbS.setProductId(nodeId);
119                 if (bridge.bridgeCommunicate(bcpSbS) && bcpSbS.isCommunicationSuccessful()) {
120                     VeluxProduct veluxProduct = bcpSbS.getProduct();
121                     if (bcpSbS.isCommunicationSuccessful()) {
122                         logger.debug("getProducts() found product {}.", veluxProduct);
123                         if (!channel.existingProducts.isRegistered(veluxProduct)) {
124                             channel.existingProducts.register(veluxProduct);
125                         }
126                     }
127                 }
128             }
129         } else {
130             logger.trace("getProducts() working on bulk retrieval.");
131             if (bridge.bridgeCommunicate(bcp) && bcp.isCommunicationSuccessful()) {
132                 for (VeluxProduct product : bcp.getProducts()) {
133                     logger.trace("getProducts() found product {} (type {}).", product.getProductName(),
134                             product.getProductType());
135                     if (!channel.existingProducts.isRegistered(product)) {
136                         logger.debug("getProducts() storing new product {}.", product);
137                         channel.existingProducts.register(product);
138                     } else {
139                         logger.debug("getProducts() storing updates for product {}.", product);
140                         channel.existingProducts.update(product);
141                     }
142                 }
143             } else {
144                 logger.trace("getProducts() finished with failure.");
145                 return false;
146             }
147         }
148         logger.debug("getProducts() finally has found products {}.", channel.existingProducts);
149         return true;
150     }
151
152     /**
153      * In case of an empty list of recognized products, the method will
154      * initiate a product retrieval using {@link #getProducts(VeluxBridge)}.
155      *
156      * @param bridge Initialized Velux bridge (communication) handler.
157      * @return true if at least one product was found, and false otherwise.
158      */
159     public boolean autoRefresh(VeluxBridge bridge) {
160         int numberOfActuators = channel.existingProducts.getNoMembers();
161         if (numberOfActuators == 0) {
162             logger.trace("autoRefresh(): is about to fetch existing products.");
163             getProducts(bridge);
164         }
165         return (numberOfActuators > 0);
166     }
167 }