2 * Copyright (c) 2010-2020 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> bridgeIndexToSerialNumber;
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 bridgeIndexToSerialNumber = new ConcurrentHashMap<>();
65 modifiedProductsByUniqueIndex = new ConcurrentHashMap<>();
68 logger.trace("VeluxExistingProducts(constructor) done.");
71 // Class access methods
73 public boolean isRegistered(String productUniqueIndexOrSerialNumber) {
74 logger.trace("isRegistered(String {}) returns {}.", productUniqueIndexOrSerialNumber,
75 existingProductsByUniqueIndex.containsKey(productUniqueIndexOrSerialNumber) ? "true" : "false");
76 return existingProductsByUniqueIndex.containsKey(productUniqueIndexOrSerialNumber);
79 public boolean isRegistered(VeluxProduct product) {
80 logger.trace("isRegistered(VeluxProduct {}) called.", product.toString());
82 return isRegistered(product.getSerialNumber());
84 return isRegistered(product.getProductUniqueIndex());
87 public boolean isRegistered(ProductBridgeIndex bridgeProductIndex) {
88 logger.trace("isRegisteredProductBridgeIndex {}) called.", bridgeProductIndex.toString());
89 if (!bridgeIndexToSerialNumber.containsKey(bridgeProductIndex.toInt())) {
92 return isRegistered(bridgeIndexToSerialNumber.get(bridgeProductIndex.toInt()));
95 public boolean register(VeluxProduct newProduct) {
96 logger.trace("register({}) called.", newProduct);
97 if (isRegistered(newProduct)) {
100 logger.trace("register() registering new product {}.", newProduct);
102 String uniqueIndex = newProduct.isV2() ? newProduct.getSerialNumber() : newProduct.getProductUniqueIndex();
103 logger.trace("register() registering by UniqueIndex {}", uniqueIndex);
104 existingProductsByUniqueIndex.put(uniqueIndex, newProduct);
106 logger.trace("register() registering by ProductBridgeIndex {}", newProduct.getBridgeProductIndex().toInt());
107 bridgeIndexToSerialNumber.put(newProduct.getBridgeProductIndex().toInt(), newProduct.getSerialNumber());
109 logger.trace("register() registering set of modifications by UniqueIndex {}", uniqueIndex);
110 modifiedProductsByUniqueIndex.put(uniqueIndex, newProduct);
117 public boolean update(ProductBridgeIndex bridgeProductIndex, int productState, int productPosition,
119 logger.debug("update(bridgeProductIndex={},productState={},productPosition={},productTarget={}) called.",
120 bridgeProductIndex.toInt(), productState, productPosition, productTarget);
121 if (!isRegistered(bridgeProductIndex)) {
122 logger.warn("update() failed as actuator (with index {}) is not registered.", bridgeProductIndex.toInt());
125 VeluxProduct thisProduct = this.get(bridgeProductIndex);
126 if (thisProduct.setState(productState) || thisProduct.setCurrentPosition(productPosition)
127 || thisProduct.setTarget(productTarget)) {
130 String uniqueIndex = thisProduct.isV2() ? thisProduct.getSerialNumber()
131 : thisProduct.getProductUniqueIndex();
132 logger.trace("update(): updating by UniqueIndex {}.", uniqueIndex);
133 existingProductsByUniqueIndex.replace(uniqueIndex, thisProduct);
134 modifiedProductsByUniqueIndex.put(uniqueIndex, thisProduct);
136 logger.trace("update() successfully finished (dirty={}).", dirty);
140 public boolean update(VeluxProduct currentProduct) {
141 logger.trace("update(currentProduct={}) called.", currentProduct);
142 return update(currentProduct.getBridgeProductIndex(), currentProduct.getState(),
143 currentProduct.getCurrentPosition(), currentProduct.getTarget());
146 public VeluxProduct get(String productUniqueIndexOrSerialNumber) {
147 logger.trace("get({}) called.", productUniqueIndexOrSerialNumber);
148 if (!isRegistered(productUniqueIndexOrSerialNumber)) {
149 return VeluxProduct.UNKNOWN;
151 return existingProductsByUniqueIndex.get(productUniqueIndexOrSerialNumber);
154 public VeluxProduct get(ProductBridgeIndex bridgeProductIndex) {
155 logger.trace("get({}) called.", bridgeProductIndex);
156 if (!isRegistered(bridgeProductIndex)) {
157 return VeluxProduct.UNKNOWN;
159 return existingProductsByUniqueIndex.get(bridgeIndexToSerialNumber.get(bridgeProductIndex.toInt()));
162 public VeluxProduct[] values() {
163 return existingProductsByUniqueIndex.values().toArray(new VeluxProduct[0]);
166 public VeluxProduct[] valuesOfModified() {
167 return modifiedProductsByUniqueIndex.values().toArray(new VeluxProduct[0]);
170 public int getNoMembers() {
171 logger.trace("getNoMembers() returns {}.", memberCount);
175 public boolean isDirty() {
176 logger.trace("isDirty() returns {}.", dirty);
180 public void resetDirtyFlag() {
181 logger.trace("resetDirtyFlag() called.");
182 modifiedProductsByUniqueIndex = new ConcurrentHashMap<>();
186 public String toString(boolean showSummary, String delimiter) {
187 StringBuilder sb = new StringBuilder();
190 sb.append(memberCount).append(" members: ");
192 for (VeluxProduct product : this.values()) {
193 sb.append(product).append(delimiter);
195 if (sb.lastIndexOf(delimiter) > 0) {
196 sb.deleteCharAt(sb.lastIndexOf(delimiter));
198 return sb.toString();
202 public String toString() {
203 return toString(true, VeluxBindingConstants.OUTPUT_VALUE_SEPARATOR);