]> git.basschouten.com Git - openhab-addons.git/blob
ae189b2f346ce662e5da0bbae9fd182fdd55f573
[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.livisismarthome.internal.manager;
14
15 import static org.openhab.binding.livisismarthome.internal.LivisiBindingConstants.BATTERY_POWERED_DEVICES;
16
17 import java.io.IOException;
18 import java.util.ArrayList;
19 import java.util.Collections;
20 import java.util.HashMap;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.Objects;
24 import java.util.Optional;
25
26 import org.eclipse.jdt.annotation.NonNullByDefault;
27 import org.eclipse.jdt.annotation.Nullable;
28 import org.openhab.binding.livisismarthome.internal.client.LivisiClient;
29 import org.openhab.binding.livisismarthome.internal.client.api.entity.capability.CapabilityDTO;
30 import org.openhab.binding.livisismarthome.internal.client.api.entity.capability.CapabilityStateDTO;
31 import org.openhab.binding.livisismarthome.internal.client.api.entity.device.DeviceDTO;
32 import org.openhab.binding.livisismarthome.internal.client.api.entity.device.DeviceStateDTO;
33 import org.openhab.binding.livisismarthome.internal.client.api.entity.link.LinkDTO;
34 import org.openhab.binding.livisismarthome.internal.client.api.entity.location.LocationDTO;
35 import org.openhab.binding.livisismarthome.internal.client.api.entity.message.MessageDTO;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39 /**
40  * @author Sven Strohschein - Initial contribution
41  *
42  *         (created by refactoring the LivisiClient class)
43  */
44 @NonNullByDefault
45 public class FullDeviceManager {
46
47     private final Logger logger = LoggerFactory.getLogger(FullDeviceManager.class);
48
49     private final LivisiClient client;
50
51     public FullDeviceManager(LivisiClient client) {
52         this.client = client;
53     }
54
55     /**
56      * Returns a {@link List} of all {@link DeviceDTO}s with the full configuration details, {@link CapabilityDTO}s and
57      * states. Calling this may take a while...
58      */
59     public List<DeviceDTO> getFullDevices() throws IOException {
60         final Map<String, LocationDTO> locationMap = createLocationMap(client);
61         final Map<String, CapabilityDTO> capabilityMap = createCapabilityMap(client);
62         final Map<String, DeviceStateDTO> deviceStateMap = createDeviceStateMap(client);
63         final Map<String, List<MessageDTO>> messageMap = createMessageMap(client);
64
65         final List<DeviceDTO> deviceList = client.getDevices(deviceStateMap.keySet());
66         for (final DeviceDTO device : deviceList) {
67             final String deviceId = device.getId();
68             initializeDevice(device, deviceStateMap.get(deviceId), locationMap, capabilityMap,
69                     getMessageList(device, messageMap));
70         }
71         return deviceList;
72     }
73
74     /**
75      * Returns the {@link DeviceDTO} with the given deviceId with full configuration details, {@link CapabilityDTO}s and
76      * states. Calling this may take a little bit longer...
77      */
78     public Optional<DeviceDTO> getFullDeviceById(final String deviceId, final boolean isSHCClassic) throws IOException {
79         final Map<String, LocationDTO> locationMap = createLocationMap(client);
80         final Map<String, CapabilityDTO> capabilityMap = createCapabilityMap(deviceId, client);
81         final List<MessageDTO> messageMap = createMessageMap(deviceId, client);
82
83         final Optional<DeviceDTO> device = client.getDeviceById(deviceId);
84         if (device.isPresent()) {
85             final DeviceStateDTO deviceState = new DeviceStateDTO();
86             deviceState.setId(deviceId);
87             deviceState.setState(client.getDeviceStateByDeviceId(deviceId, isSHCClassic));
88
89             initializeDevice(device.get(), deviceState, locationMap, capabilityMap, messageMap);
90         }
91         return device;
92     }
93
94     private void initializeDevice(DeviceDTO device, @Nullable DeviceStateDTO deviceState,
95             Map<String, LocationDTO> locationMap, Map<String, CapabilityDTO> capabilityMap,
96             List<MessageDTO> messageList) {
97         device.setDeviceState(deviceState);
98
99         if (isBatteryPowered(device)) {
100             device.setIsBatteryPowered(true);
101         }
102
103         device.setLocation(locationMap.get(device.getLocationId()));
104
105         device.setCapabilityMap(createDeviceCapabilityMap(device, capabilityMap));
106
107         device.setMessageList(messageList);
108     }
109
110     private static boolean isBatteryPowered(DeviceDTO device) {
111         return BATTERY_POWERED_DEVICES.contains(device.getType());
112     }
113
114     private List<MessageDTO> getMessageList(DeviceDTO device, Map<String, List<MessageDTO>> messageMap) {
115         return Objects.requireNonNullElse(messageMap.get(device.getId()), Collections.emptyList());
116     }
117
118     private static Map<String, LocationDTO> createLocationMap(LivisiClient client) throws IOException {
119         final List<LocationDTO> locationList = client.getLocations();
120         final Map<String, LocationDTO> locationMap = new HashMap<>(locationList.size());
121         for (final LocationDTO location : locationList) {
122             locationMap.put(location.getId(), location);
123         }
124         return locationMap;
125     }
126
127     private static Map<String, CapabilityStateDTO> createCapabilityStateMap(LivisiClient client) throws IOException {
128         final List<CapabilityStateDTO> capabilityStateList = client.getCapabilityStates();
129         final Map<String, CapabilityStateDTO> capabilityStateMap = new HashMap<>(capabilityStateList.size());
130         for (final CapabilityStateDTO capabilityState : capabilityStateList) {
131             capabilityStateMap.put(capabilityState.getId(), capabilityState);
132         }
133         return capabilityStateMap;
134     }
135
136     private static Map<String, CapabilityDTO> createCapabilityMap(LivisiClient client) throws IOException {
137         final Map<String, CapabilityStateDTO> capabilityStateMap = createCapabilityStateMap(client);
138         final List<CapabilityDTO> capabilityList = client.getCapabilities();
139
140         return initializeCapabilities(capabilityStateMap, capabilityList);
141     }
142
143     private static Map<String, CapabilityDTO> createCapabilityMap(String deviceId, LivisiClient client)
144             throws IOException {
145         final Map<String, CapabilityStateDTO> capabilityStateMap = createCapabilityStateMap(client);
146         final List<CapabilityDTO> capabilityList = client.getCapabilitiesForDevice(deviceId);
147
148         return initializeCapabilities(capabilityStateMap, capabilityList);
149     }
150
151     private static Map<String, CapabilityDTO> initializeCapabilities(Map<String, CapabilityStateDTO> capabilityStateMap,
152             List<CapabilityDTO> capabilityList) {
153         final Map<String, CapabilityDTO> capabilityMap = new HashMap<>(capabilityList.size());
154         for (final CapabilityDTO capability : capabilityList) {
155             String capabilityId = capability.getId();
156
157             CapabilityStateDTO capabilityState = capabilityStateMap.get(capabilityId);
158             capability.setCapabilityState(capabilityState);
159
160             capabilityMap.put(capabilityId, capability);
161         }
162         return capabilityMap;
163     }
164
165     private static Map<String, CapabilityDTO> createDeviceCapabilityMap(DeviceDTO device,
166             Map<String, CapabilityDTO> capabilityMap) {
167         final HashMap<String, CapabilityDTO> deviceCapabilityMap = new HashMap<>();
168         for (final String capabilityValue : device.getCapabilities()) {
169             final CapabilityDTO capability = capabilityMap.get(LinkDTO.getId(capabilityValue));
170             if (capability != null) {
171                 final String capabilityId = capability.getId();
172                 deviceCapabilityMap.put(capabilityId, capability);
173             }
174         }
175         return deviceCapabilityMap;
176     }
177
178     private static Map<String, DeviceStateDTO> createDeviceStateMap(LivisiClient client) throws IOException {
179         final List<DeviceStateDTO> deviceStateList = client.getDeviceStates();
180         final Map<String, DeviceStateDTO> deviceStateMap = new HashMap<>(deviceStateList.size());
181         for (final DeviceStateDTO deviceState : deviceStateList) {
182             deviceStateMap.put(deviceState.getId(), deviceState);
183         }
184         return deviceStateMap;
185     }
186
187     private List<MessageDTO> createMessageMap(String deviceId, LivisiClient client) throws IOException {
188         final List<MessageDTO> messages = client.getMessages();
189         final List<MessageDTO> messageList = new ArrayList<>();
190         final String deviceIdPath = "/device/" + deviceId;
191
192         for (final MessageDTO message : messages) {
193             logger.trace("Message Type {} with ID {}", message.getType(), message.getId());
194             if (message.getDevices() != null && !message.getDevices().isEmpty()) {
195                 for (final String li : message.getDevices()) {
196                     if (deviceIdPath.equals(li)) {
197                         messageList.add(message);
198                     }
199                 }
200             }
201         }
202         return messageList;
203     }
204
205     private static Map<String, List<MessageDTO>> createMessageMap(LivisiClient client) throws IOException {
206         final List<MessageDTO> messageList = client.getMessages();
207         final Map<String, List<MessageDTO>> deviceMessageMap = new HashMap<>();
208         for (final MessageDTO message : messageList) {
209             if (message.getDevices() != null && !message.getDevices().isEmpty()) {
210                 final String deviceId = message.getDevices().get(0).replace("/device/", "");
211
212                 // could get optimized with computeIfAbsent, but the non-null checks doesn't understand that and
213                 // produces compiler warnings...
214                 List<MessageDTO> ml = deviceMessageMap.get(deviceId);
215                 if (ml == null) {
216                     ml = new ArrayList<>();
217                     deviceMessageMap.put(deviceId, ml);
218                 }
219                 ml.add(message);
220             }
221         }
222         return deviceMessageMap;
223     }
224 }