]> git.basschouten.com Git - openhab-addons.git/blob
967e51568cd121bd2adc45538994a2650b654a07
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2021 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.innogysmarthome.internal.manager;
14
15 import java.io.IOException;
16 import java.util.Collection;
17 import java.util.Collections;
18 import java.util.HashMap;
19 import java.util.List;
20 import java.util.Map;
21 import java.util.concurrent.ConcurrentHashMap;
22
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.eclipse.jdt.annotation.Nullable;
25 import org.openhab.binding.innogysmarthome.internal.InnogyBindingConstants;
26 import org.openhab.binding.innogysmarthome.internal.client.InnogyClient;
27 import org.openhab.binding.innogysmarthome.internal.client.entity.capability.Capability;
28 import org.openhab.binding.innogysmarthome.internal.client.entity.capability.State;
29 import org.openhab.binding.innogysmarthome.internal.client.entity.device.Device;
30 import org.openhab.binding.innogysmarthome.internal.client.entity.link.Link;
31 import org.openhab.binding.innogysmarthome.internal.client.entity.message.Message;
32 import org.openhab.binding.innogysmarthome.internal.client.exception.ApiException;
33 import org.openhab.binding.innogysmarthome.internal.client.exception.AuthenticationException;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36
37 /**
38  * Manages the structure of the {@link Device}s and the calls to the {@link InnogyClient} to load the {@link Device}
39  * data from the innogy SmartHome web service.
40  *
41  * @author Oliver Kuhl - Initial contribution
42  *
43  */
44 @NonNullByDefault
45 public class DeviceStructureManager {
46
47     private final Logger logger = LoggerFactory.getLogger(DeviceStructureManager.class);
48
49     private final InnogyClient client;
50     private final Map<String, Device> deviceMap;
51     private final Map<String, Device> capabilityIdToDeviceMap;
52     private String bridgeDeviceId = "";
53
54     /**
55      * Constructs the {@link DeviceStructureManager}.
56      *
57      * @param client the {@link InnogyClient}
58      */
59     public DeviceStructureManager(InnogyClient client) {
60         this.client = client;
61         deviceMap = Collections.synchronizedMap(new HashMap<>());
62         capabilityIdToDeviceMap = new ConcurrentHashMap<>();
63     }
64
65     /**
66      * Returns the {@link #deviceMap}, a map with the device id and the device.
67      *
68      * @return
69      */
70     public Map<String, Device> getDeviceMap() {
71         return deviceMap;
72     }
73
74     /**
75      * Loads all device data from the bridge and stores the {@link Device}s and their states in the
76      * {@link DeviceStructureManager}.
77      *
78      * @throws IOException
79      * @throws ApiException
80      * @throws AuthenticationException
81      */
82     public void refreshDevices() throws IOException, ApiException, AuthenticationException {
83         deviceMap.clear();
84         capabilityIdToDeviceMap.clear();
85         List<Device> devices = client.getFullDevices();
86         for (Device d : devices) {
87             handleRefreshedDevice(d);
88         }
89     }
90
91     /**
92      * Refreshs the {@link Device} with the given id and stores it in the {@link DeviceStructureManager}.
93      *
94      * @param deviceId
95      * @throws IOException
96      * @throws ApiException
97      * @throws AuthenticationException
98      */
99     public void refreshDevice(String deviceId) throws IOException, ApiException, AuthenticationException {
100         logger.trace("Refreshing Device with id '{}'", deviceId);
101         Device d = client.getFullDeviceById(deviceId);
102         handleRefreshedDevice(d);
103     }
104
105     /**
106      * Stores the newly refreshed {@link Device} in the {@link DeviceStructureManager} structure and logs the
107      * {@link Device}s details and state, if the debug logging is enabled.
108      *
109      * @param d the {@link Device}
110      */
111     private void handleRefreshedDevice(Device d) {
112         if (InnogyBindingConstants.SUPPORTED_DEVICES.contains(d.getType())) {
113             addDeviceToStructure(d);
114         } else {
115             logger.debug("Device {}:'{}' by {} ({}) ignored - UNSUPPORTED.", d.getType(), d.getConfig().getName(),
116                     d.getManufacturer(), d.getId());
117             logger.debug("====================================");
118             return;
119         }
120
121         if (d.isController()) {
122             bridgeDeviceId = d.getId();
123         }
124
125         if (logger.isDebugEnabled()) {
126             try {
127                 logger.debug("Device {}:'{}@{}' by {} ({}) loaded.", d.getType(), d.getConfig().getName(),
128                         d.getLocation() != null ? d.getLocation().getName() : "<none>", d.getManufacturer(), d.getId());
129                 for (Capability c : d.getCapabilityMap().values()) {
130                     logger.debug("> CAP: {}/{} ({})", c.getType(), c.getName(), c.getId());
131                     if (d.isRadioDevice() && !d.isReachable()) {
132                         logger.debug(">> CAP-State: unknown (device NOT REACHABLE).");
133                     } else {
134                         if (c.hasState()) {
135                             final State state = c.getCapabilityState().getState();
136                         } else {
137                             logger.debug(">> CAP-State: unknown (NULL)");
138                         }
139                     }
140                 }
141             } catch (RuntimeException e) {
142                 logger.debug("Error during logging: ", e);
143             }
144             logger.debug("====================================");
145         }
146     }
147
148     /**
149      * Adds the {@link Device} to the structure.
150      *
151      * @param device
152      */
153     public void addDeviceToStructure(Device device) {
154         if (device.getId() != null) {
155             getDeviceMap().put(device.getId(), device);
156         }
157
158         for (String cl : device.getCapabilityLinkList()) {
159             capabilityIdToDeviceMap.put(Link.getId(cl), device);
160         }
161     }
162
163     /**
164      * Returns the {@link Device} with the given id.
165      *
166      * @param id
167      * @return the {@link Device} or null, if it does not exist
168      */
169     public @Nullable Device getDeviceById(String id) {
170         logger.debug("getDeviceById {}:{}", id, getDeviceMap().containsKey(id));
171         return getDeviceMap().get(id);
172     }
173
174     /**
175      * Returns the {@link Device}, that provides the given capability.
176      *
177      * @param capabilityId
178      * @return {@link Device} or null
179      */
180     public @Nullable Device getDeviceByCapabilityId(String capabilityId) {
181         return capabilityIdToDeviceMap.get(capabilityId);
182     }
183
184     /**
185      * Returns the bridge {@link Device}.
186      *
187      * @return
188      */
189     public @Nullable Device getBridgeDevice() {
190         return getDeviceMap().get(bridgeDeviceId);
191     }
192
193     /**
194      * Returns a {@link Collection} of all {@link Device}s handled by the {@link DeviceStructureManager}.
195      *
196      * @return
197      */
198     public Collection<Device> getDeviceList() {
199         return Collections.unmodifiableCollection(getDeviceMap().values());
200     }
201
202     /**
203      * Returns the {@link Device}, that has the {@link Message} with the given messageId.
204      *
205      * @param messageId the id of the {@link Message}
206      * @return the {@link Device} or null if none found
207      */
208     public @Nullable Device getDeviceWithMessageId(String messageId) {
209         logger.trace("Getting Device with MessageId '{}'", messageId);
210         for (Device d : getDeviceMap().values()) {
211             if (d.hasMessages()) {
212                 for (Message m : d.getMessageList()) {
213                     if (messageId.equals(m.getId())) {
214                         return d;
215                     }
216                 }
217             }
218         }
219         return null;
220     }
221
222     /**
223      * Returns the id of the {@link Capability} for {@link Device} with the given id and the given capabilityType.
224      *
225      * @param deviceId
226      * @param capabilityType
227      * @return the id of the found {@link Capability} or null
228      */
229     public @Nullable String getCapabilityId(String deviceId, String capabilityType) {
230         Device device = getDeviceMap().get(deviceId);
231         for (Capability c : device.getCapabilityMap().values()) {
232             if (c.getType().equals(capabilityType)) {
233                 return c.getId();
234             }
235         }
236         return null;
237     }
238 }