]> git.basschouten.com Git - openhab-addons.git/blob
0829b86201699d86f1eca203e96b9eee893a4032
[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
61         final Map<String, LocationDTO> locationMap = createLocationMap(client);
62         final Map<String, CapabilityDTO> capabilityMap = createCapabilityMap(client);
63         final Map<String, DeviceStateDTO> deviceStateMap = createDeviceStateMap(client);
64         final Map<String, List<MessageDTO>> messageMap = createMessageMap(client);
65
66         final List<DeviceDTO> deviceList = client.getDevices(deviceStateMap.keySet());
67         for (final DeviceDTO device : deviceList) {
68             final String deviceId = device.getId();
69             initializeDevice(device, deviceStateMap.get(deviceId), locationMap, capabilityMap,
70                     getMessageList(device, messageMap));
71         }
72         return deviceList;
73     }
74
75     /**
76      * Returns the {@link DeviceDTO} with the given deviceId with full configuration details, {@link CapabilityDTO}s and
77      * states. Calling this may take a little bit longer...
78      */
79     public Optional<DeviceDTO> getFullDeviceById(final String deviceId, final boolean isSHCClassic) throws IOException {
80         final Map<String, LocationDTO> locationMap = createLocationMap(client);
81         final Map<String, CapabilityDTO> capabilityMap = createCapabilityMap(deviceId, client);
82         final List<MessageDTO> messageMap = createMessageMap(deviceId, client);
83
84         final Optional<DeviceDTO> device = client.getDeviceById(deviceId);
85         if (device.isPresent()) {
86             final DeviceStateDTO deviceState = new DeviceStateDTO();
87             deviceState.setId(deviceId);
88             deviceState.setState(client.getDeviceStateByDeviceId(deviceId, isSHCClassic));
89
90             initializeDevice(device.get(), deviceState, locationMap, capabilityMap, messageMap);
91         }
92         return device;
93     }
94
95     private void initializeDevice(DeviceDTO device, @Nullable DeviceStateDTO deviceState,
96             Map<String, LocationDTO> locationMap, Map<String, CapabilityDTO> capabilityMap,
97             List<MessageDTO> messageList) {
98
99         device.setDeviceState(deviceState);
100
101         if (isBatteryPowered(device)) {
102             device.setIsBatteryPowered(true);
103         }
104
105         device.setLocation(locationMap.get(device.getLocationId()));
106
107         device.setCapabilityMap(createDeviceCapabilityMap(device, capabilityMap));
108
109         device.setMessageList(messageList);
110     }
111
112     private static boolean isBatteryPowered(DeviceDTO device) {
113         return BATTERY_POWERED_DEVICES.contains(device.getType());
114     }
115
116     private List<MessageDTO> getMessageList(DeviceDTO device, Map<String, List<MessageDTO>> messageMap) {
117         return Objects.requireNonNullElse(messageMap.get(device.getId()), Collections.emptyList());
118     }
119
120     private static Map<String, LocationDTO> createLocationMap(LivisiClient client) throws IOException {
121         final List<LocationDTO> locationList = client.getLocations();
122         final Map<String, LocationDTO> locationMap = new HashMap<>(locationList.size());
123         for (final LocationDTO location : locationList) {
124             locationMap.put(location.getId(), location);
125         }
126         return locationMap;
127     }
128
129     private static Map<String, CapabilityStateDTO> createCapabilityStateMap(LivisiClient client) throws IOException {
130         final List<CapabilityStateDTO> capabilityStateList = client.getCapabilityStates();
131         final Map<String, CapabilityStateDTO> capabilityStateMap = new HashMap<>(capabilityStateList.size());
132         for (final CapabilityStateDTO capabilityState : capabilityStateList) {
133             capabilityStateMap.put(capabilityState.getId(), capabilityState);
134         }
135         return capabilityStateMap;
136     }
137
138     private static Map<String, CapabilityDTO> createCapabilityMap(LivisiClient client) throws IOException {
139
140         final Map<String, CapabilityStateDTO> capabilityStateMap = createCapabilityStateMap(client);
141         final List<CapabilityDTO> capabilityList = client.getCapabilities();
142
143         return initializeCapabilities(capabilityStateMap, capabilityList);
144     }
145
146     private static Map<String, CapabilityDTO> createCapabilityMap(String deviceId, LivisiClient client)
147             throws IOException {
148
149         final Map<String, CapabilityStateDTO> capabilityStateMap = createCapabilityStateMap(client);
150         final List<CapabilityDTO> capabilityList = client.getCapabilitiesForDevice(deviceId);
151
152         return initializeCapabilities(capabilityStateMap, capabilityList);
153     }
154
155     private static Map<String, CapabilityDTO> initializeCapabilities(Map<String, CapabilityStateDTO> capabilityStateMap,
156             List<CapabilityDTO> capabilityList) {
157         final Map<String, CapabilityDTO> capabilityMap = new HashMap<>(capabilityList.size());
158         for (final CapabilityDTO capability : capabilityList) {
159             String capabilityId = capability.getId();
160
161             CapabilityStateDTO capabilityState = capabilityStateMap.get(capabilityId);
162             capability.setCapabilityState(capabilityState);
163
164             capabilityMap.put(capabilityId, capability);
165         }
166         return capabilityMap;
167     }
168
169     private static Map<String, CapabilityDTO> createDeviceCapabilityMap(DeviceDTO device,
170             Map<String, CapabilityDTO> capabilityMap) {
171
172         final HashMap<String, CapabilityDTO> deviceCapabilityMap = new HashMap<>();
173         for (final String capabilityValue : device.getCapabilities()) {
174             final CapabilityDTO capability = capabilityMap.get(LinkDTO.getId(capabilityValue));
175             if (capability != null) {
176                 final String capabilityId = capability.getId();
177                 deviceCapabilityMap.put(capabilityId, capability);
178             }
179         }
180         return deviceCapabilityMap;
181     }
182
183     private static Map<String, DeviceStateDTO> createDeviceStateMap(LivisiClient client) throws IOException {
184         final List<DeviceStateDTO> deviceStateList = client.getDeviceStates();
185         final Map<String, DeviceStateDTO> deviceStateMap = new HashMap<>(deviceStateList.size());
186         for (final DeviceStateDTO deviceState : deviceStateList) {
187             deviceStateMap.put(deviceState.getId(), deviceState);
188         }
189         return deviceStateMap;
190     }
191
192     private List<MessageDTO> createMessageMap(String deviceId, LivisiClient client) throws IOException {
193         final List<MessageDTO> messages = client.getMessages();
194         final List<MessageDTO> messageList = new ArrayList<>();
195         final String deviceIdPath = "/device/" + deviceId;
196
197         for (final MessageDTO message : messages) {
198             logger.trace("Message Type {} with ID {}", message.getType(), message.getId());
199             if (message.getDevices() != null && !message.getDevices().isEmpty()) {
200                 for (final String li : message.getDevices()) {
201                     if (deviceIdPath.equals(li)) {
202                         messageList.add(message);
203                     }
204                 }
205             }
206         }
207         return messageList;
208     }
209
210     private static Map<String, List<MessageDTO>> createMessageMap(LivisiClient client) throws IOException {
211         final List<MessageDTO> messageList = client.getMessages();
212         final Map<String, List<MessageDTO>> deviceMessageMap = new HashMap<>();
213         for (final MessageDTO message : messageList) {
214             if (message.getDevices() != null && !message.getDevices().isEmpty()) {
215                 final String deviceId = message.getDevices().get(0).replace("/device/", "");
216
217                 // could get optimized with computeIfAbsent, but the non-null checks doesn't understand that and
218                 // produces compiler warnings...
219                 List<MessageDTO> ml = deviceMessageMap.get(deviceId);
220                 if (ml == null) {
221                     ml = new ArrayList<>();
222                     deviceMessageMap.put(deviceId, ml);
223                 }
224                 ml.add(message);
225             }
226         }
227         return deviceMessageMap;
228     }
229 }