]> git.basschouten.com Git - openhab-addons.git/blob
a222d9596c8d1a047b20291f163138c79961b1b2
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2022 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.things;
14
15 import java.util.Map;
16 import java.util.concurrent.ConcurrentHashMap;
17
18 import org.eclipse.jdt.annotation.NonNullByDefault;
19 import org.openhab.binding.velux.internal.VeluxBindingConstants;
20 import org.openhab.binding.velux.internal.things.VeluxProduct.ProductBridgeIndex;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
23
24 /**
25  * Combined set of product informations provided by the <B>Velux</B> bridge,
26  * which can be used for later interactions.
27  * <P>
28  * The following class access methods exist:
29  * <UL>
30  * <LI>{@link VeluxExistingProducts#isRegistered} for querying existence of a {@link VeluxProduct},</LI>
31  * <LI>{@link VeluxExistingProducts#register} for storing a {@link VeluxProduct},</LI>
32  * <LI>{@link VeluxExistingProducts#update} for updating/storing of a {@link VeluxProduct},</LI>
33  * <LI>{@link VeluxExistingProducts#get} for retrieval of a {@link VeluxProduct},</LI>
34  * <LI>{@link VeluxExistingProducts#values} for retrieval of all {@link VeluxProduct}s,</LI>
35  * <LI>{@link VeluxExistingProducts#getNoMembers} for retrieval of the number of all {@link VeluxProduct}s,</LI>
36  * <LI>{@link VeluxExistingProducts#toString} for a descriptive string representation.</LI>
37  * </UL>
38  *
39  * @see VeluxProduct
40  *
41  * @author Guenther Schreiner - initial contribution.
42  */
43 @NonNullByDefault
44 public class VeluxExistingProducts {
45     private final Logger logger = LoggerFactory.getLogger(VeluxExistingProducts.class);
46
47     // Type definitions, class-internal variables
48
49     private Map<String, VeluxProduct> existingProductsByUniqueIndex;
50     private Map<Integer, String> bridgeIndexToUniqueIndex;
51     private Map<String, VeluxProduct> modifiedProductsByUniqueIndex;
52     private int memberCount;
53
54     /*
55      * Value to flag any changes towards the getter.
56      */
57     private boolean dirty;
58
59     // Constructor methods
60
61     public VeluxExistingProducts() {
62         logger.trace("VeluxExistingProducts(constructor) called.");
63         existingProductsByUniqueIndex = new ConcurrentHashMap<>();
64         bridgeIndexToUniqueIndex = new ConcurrentHashMap<>();
65         modifiedProductsByUniqueIndex = new ConcurrentHashMap<>();
66         memberCount = 0;
67         dirty = true;
68         logger.trace("VeluxExistingProducts(constructor) done.");
69     }
70
71     // Class access methods
72
73     public boolean isRegistered(String productUniqueIndex) {
74         boolean result = existingProductsByUniqueIndex.containsKey(productUniqueIndex);
75         logger.trace("isRegistered(String {}) returns {}.", productUniqueIndex, result);
76         return result;
77     }
78
79     public boolean isRegistered(VeluxProduct product) {
80         boolean result = existingProductsByUniqueIndex.containsKey(product.getProductUniqueIndex());
81         logger.trace("isRegistered(VeluxProduct {}) returns {}.", product, result);
82         return result;
83     }
84
85     public boolean isRegistered(ProductBridgeIndex bridgeProductIndex) {
86         boolean result = bridgeIndexToUniqueIndex.containsKey(bridgeProductIndex.toInt());
87         logger.trace("isRegistered(ProductBridgeIndex {}) returns {}.", bridgeProductIndex, result);
88         return result;
89     }
90
91     public boolean register(VeluxProduct newProduct) {
92         logger.trace("register({}) called.", newProduct);
93         if (isRegistered(newProduct)) {
94             return false;
95         }
96         logger.trace("register() registering new product {}.", newProduct);
97
98         String uniqueIndex = newProduct.getProductUniqueIndex();
99         logger.trace("register() registering by UniqueIndex {}", uniqueIndex);
100         existingProductsByUniqueIndex.put(uniqueIndex, newProduct);
101
102         logger.trace("register() registering by ProductBridgeIndex {}", newProduct.getBridgeProductIndex().toInt());
103         bridgeIndexToUniqueIndex.put(newProduct.getBridgeProductIndex().toInt(), uniqueIndex);
104
105         logger.trace("register() registering set of modifications by UniqueIndex {}", uniqueIndex);
106         modifiedProductsByUniqueIndex.put(uniqueIndex, newProduct);
107
108         memberCount++;
109         dirty = true;
110         return true;
111     }
112
113     public boolean update(ProductBridgeIndex bridgeProductIndex, int productState, int productPosition,
114             int productTarget) {
115         logger.debug("update(bridgeProductIndex={},productState={},productPosition={},productTarget={}) called.",
116                 bridgeProductIndex.toInt(), productState, productPosition, productTarget);
117         if (!isRegistered(bridgeProductIndex)) {
118             logger.warn("update() failed as actuator (with index {}) is not registered.", bridgeProductIndex.toInt());
119             return false;
120         }
121         VeluxProduct thisProduct = this.get(bridgeProductIndex);
122         dirty |= thisProduct.setState(productState);
123         dirty |= thisProduct.setCurrentPosition(productPosition);
124         dirty |= thisProduct.setTarget(productTarget);
125         if (dirty) {
126             String uniqueIndex = thisProduct.getProductUniqueIndex();
127             logger.trace("update(): updating by UniqueIndex {}.", uniqueIndex);
128             existingProductsByUniqueIndex.replace(uniqueIndex, thisProduct);
129             modifiedProductsByUniqueIndex.put(uniqueIndex, thisProduct);
130         }
131         logger.trace("update() successfully finished (dirty={}).", dirty);
132         return true;
133     }
134
135     public boolean update(VeluxProduct currentProduct) {
136         logger.trace("update(currentProduct={}) called.", currentProduct);
137         return update(currentProduct.getBridgeProductIndex(), currentProduct.getState(),
138                 currentProduct.getCurrentPosition(), currentProduct.getTarget());
139     }
140
141     public VeluxProduct get(String productUniqueIndex) {
142         logger.trace("get({}) called.", productUniqueIndex);
143         return existingProductsByUniqueIndex.getOrDefault(productUniqueIndex, VeluxProduct.UNKNOWN);
144     }
145
146     public VeluxProduct get(ProductBridgeIndex bridgeProductIndex) {
147         logger.trace("get({}) called.", bridgeProductIndex);
148         String unique = bridgeIndexToUniqueIndex.get(bridgeProductIndex.toInt());
149         return unique != null ? existingProductsByUniqueIndex.getOrDefault(unique, VeluxProduct.UNKNOWN)
150                 : VeluxProduct.UNKNOWN;
151     }
152
153     public VeluxProduct[] values() {
154         return existingProductsByUniqueIndex.values().toArray(new VeluxProduct[0]);
155     }
156
157     public VeluxProduct[] valuesOfModified() {
158         return modifiedProductsByUniqueIndex.values().toArray(new VeluxProduct[0]);
159     }
160
161     public int getNoMembers() {
162         logger.trace("getNoMembers() returns {}.", memberCount);
163         return memberCount;
164     }
165
166     public boolean isDirty() {
167         logger.trace("isDirty() returns {}.", dirty);
168         return dirty;
169     }
170
171     public void resetDirtyFlag() {
172         logger.trace("resetDirtyFlag() called.");
173         modifiedProductsByUniqueIndex = new ConcurrentHashMap<>();
174         dirty = false;
175     }
176
177     public String toString(boolean showSummary, String delimiter) {
178         StringBuilder sb = new StringBuilder();
179
180         if (showSummary) {
181             sb.append(memberCount).append(" members: ");
182         }
183         for (VeluxProduct product : this.values()) {
184             sb.append(product).append(delimiter);
185         }
186         if (sb.lastIndexOf(delimiter) > 0) {
187             sb.deleteCharAt(sb.lastIndexOf(delimiter));
188         }
189         return sb.toString();
190     }
191
192     @Override
193     public String toString() {
194         return toString(true, VeluxBindingConstants.OUTPUT_VALUE_SEPARATOR);
195     }
196 }