2 * Copyright (c) 2010-2022 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.velux.internal.things;
16 import java.util.concurrent.ConcurrentHashMap;
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;
25 * Combined set of product informations provided by the <B>Velux</B> bridge,
26 * which can be used for later interactions.
28 * The following class access methods exist:
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>
41 * @author Guenther Schreiner - initial contribution.
44 public class VeluxExistingProducts {
45 private final Logger logger = LoggerFactory.getLogger(VeluxExistingProducts.class);
47 // Type definitions, class-internal variables
49 private Map<String, VeluxProduct> existingProductsByUniqueIndex;
50 private Map<Integer, String> bridgeIndexToUniqueIndex;
51 private Map<String, VeluxProduct> modifiedProductsByUniqueIndex;
52 private int memberCount;
55 * Value to flag any changes towards the getter.
57 private boolean dirty;
59 // Constructor methods
61 public VeluxExistingProducts() {
62 logger.trace("VeluxExistingProducts(constructor) called.");
63 existingProductsByUniqueIndex = new ConcurrentHashMap<>();
64 bridgeIndexToUniqueIndex = new ConcurrentHashMap<>();
65 modifiedProductsByUniqueIndex = new ConcurrentHashMap<>();
68 logger.trace("VeluxExistingProducts(constructor) done.");
71 // Class access methods
73 public boolean isRegistered(String productUniqueIndex) {
74 boolean result = existingProductsByUniqueIndex.containsKey(productUniqueIndex);
75 logger.trace("isRegistered(String {}) returns {}.", productUniqueIndex, result);
79 public boolean isRegistered(VeluxProduct product) {
80 boolean result = existingProductsByUniqueIndex.containsKey(product.getProductUniqueIndex());
81 logger.trace("isRegistered(VeluxProduct {}) returns {}.", product, result);
85 public boolean isRegistered(ProductBridgeIndex bridgeProductIndex) {
86 boolean result = bridgeIndexToUniqueIndex.containsKey(bridgeProductIndex.toInt());
87 logger.trace("isRegistered(ProductBridgeIndex {}) returns {}.", bridgeProductIndex, result);
91 public boolean register(VeluxProduct newProduct) {
92 logger.trace("register({}) called.", newProduct);
93 if (isRegistered(newProduct)) {
96 logger.trace("register() registering new product {}.", newProduct);
98 String uniqueIndex = newProduct.getProductUniqueIndex();
99 logger.trace("register() registering by UniqueIndex {}", uniqueIndex);
100 existingProductsByUniqueIndex.put(uniqueIndex, newProduct);
102 logger.trace("register() registering by ProductBridgeIndex {}", newProduct.getBridgeProductIndex().toInt());
103 bridgeIndexToUniqueIndex.put(newProduct.getBridgeProductIndex().toInt(), uniqueIndex);
105 logger.trace("register() registering set of modifications by UniqueIndex {}", uniqueIndex);
106 modifiedProductsByUniqueIndex.put(uniqueIndex, newProduct);
113 public boolean update(ProductBridgeIndex bridgeProductIndex, int productState, int productPosition,
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());
121 VeluxProduct thisProduct = this.get(bridgeProductIndex);
122 dirty |= thisProduct.setState(productState);
123 dirty |= thisProduct.setCurrentPosition(productPosition);
124 dirty |= thisProduct.setTarget(productTarget);
126 String uniqueIndex = thisProduct.getProductUniqueIndex();
127 logger.trace("update(): updating by UniqueIndex {}.", uniqueIndex);
128 existingProductsByUniqueIndex.replace(uniqueIndex, thisProduct);
129 modifiedProductsByUniqueIndex.put(uniqueIndex, thisProduct);
131 logger.trace("update() successfully finished (dirty={}).", dirty);
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());
141 public VeluxProduct get(String productUniqueIndex) {
142 logger.trace("get({}) called.", productUniqueIndex);
143 return existingProductsByUniqueIndex.getOrDefault(productUniqueIndex, VeluxProduct.UNKNOWN);
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;
153 public VeluxProduct[] values() {
154 return existingProductsByUniqueIndex.values().toArray(new VeluxProduct[0]);
157 public VeluxProduct[] valuesOfModified() {
158 return modifiedProductsByUniqueIndex.values().toArray(new VeluxProduct[0]);
161 public int getNoMembers() {
162 logger.trace("getNoMembers() returns {}.", memberCount);
166 public boolean isDirty() {
167 logger.trace("isDirty() returns {}.", dirty);
171 public void resetDirtyFlag() {
172 logger.trace("resetDirtyFlag() called.");
173 modifiedProductsByUniqueIndex = new ConcurrentHashMap<>();
177 public String toString(boolean showSummary, String delimiter) {
178 StringBuilder sb = new StringBuilder();
181 sb.append(memberCount).append(" members: ");
183 for (VeluxProduct product : this.values()) {
184 sb.append(product).append(delimiter);
186 if (sb.lastIndexOf(delimiter) > 0) {
187 sb.deleteCharAt(sb.lastIndexOf(delimiter));
189 return sb.toString();
193 public String toString() {
194 return toString(true, VeluxBindingConstants.OUTPUT_VALUE_SEPARATOR);