]> git.basschouten.com Git - openhab-addons.git/blob
866c20cd241c05d7cd8e119c3a2babb39e4ac504
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 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.amazonechocontrol.internal.smarthome;
14
15 import java.util.Date;
16 import java.util.HashMap;
17 import java.util.HashSet;
18 import java.util.List;
19 import java.util.Map;
20 import java.util.Set;
21
22 import org.eclipse.jdt.annotation.NonNullByDefault;
23 import org.openhab.binding.amazonechocontrol.internal.jsons.JsonSmartHomeCapabilities.SmartHomeCapability;
24 import org.openhab.binding.amazonechocontrol.internal.jsons.JsonSmartHomeDevices.DriverIdentity;
25 import org.openhab.binding.amazonechocontrol.internal.jsons.JsonSmartHomeDevices.SmartHomeDevice;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29 /**
30  * Handles the update interval calculation
31  *
32  * @author Michael Geramb - Initial contribution
33  */
34 @NonNullByDefault
35 public class SmartHomeDeviceStateGroupUpdateCalculator {
36     private final Logger logger = LoggerFactory.getLogger(SmartHomeDeviceStateGroupUpdateCalculator.class);
37
38     private static final Integer UPDATE_INTERVAL_PRIVATE_SKILLS_IN_SECONDS = 10;
39     private static final Integer UPDATE_INTERVAL_PRIVATE_SKILLS_IN_SECONDS_TRACE = 600;
40     private static final Integer UPDATE_INTERVAL_ACOUSTIC_EVENTS_IN_SECONDS = 10;
41     private Integer updateIntervalAmazonInSeconds;
42     private Integer updateIntervalSkillsInSeconds;
43
44     private static class UpdateGroup {
45         private final int intervalInSeconds;
46         private Date lastUpdated;
47
48         public UpdateGroup(int intervalInSeconds) {
49             this.intervalInSeconds = intervalInSeconds;
50             this.lastUpdated = new Date(0);
51         }
52     }
53
54     private final Map<Integer, UpdateGroup> updateGroups = new HashMap<>();
55
56     public SmartHomeDeviceStateGroupUpdateCalculator(int updateIntervalAmazonInSeconds,
57             int updateIntervalSkillsInSeconds) {
58         this.updateIntervalAmazonInSeconds = updateIntervalAmazonInSeconds;
59         this.updateIntervalSkillsInSeconds = updateIntervalSkillsInSeconds;
60     }
61
62     private Integer getUpdateIntervalInSeconds(SmartHomeDevice shd) {
63         Integer updateIntervalInSeconds = shd.updateIntervalInSeconds;
64         if (updateIntervalInSeconds != null) {
65             return updateIntervalInSeconds;
66         }
67         SmartHomeCapability[] capabilities = shd.capabilities;
68         if (capabilities != null) {
69             for (SmartHomeCapability capability : capabilities) {
70                 if (capability != null && HandlerAcousticEventSensor.INTERFACE.equals(capability.interfaceName)) {
71                     updateIntervalInSeconds = UPDATE_INTERVAL_ACOUSTIC_EVENTS_IN_SECONDS;
72                     break;
73                 }
74             }
75         }
76         if (updateIntervalInSeconds == null) {
77             String manufacturerName = shd.manufacturerName;
78             if (manufacturerName != null && ("openHAB".equalsIgnoreCase(manufacturerName)
79                     || manufacturerName.toLowerCase().startsWith("iobroker"))) {
80                 // OpenHAB or ioBroker skill
81                 if (logger.isTraceEnabled()) {
82                     updateIntervalInSeconds = UPDATE_INTERVAL_PRIVATE_SKILLS_IN_SECONDS_TRACE;
83                 } else {
84                     updateIntervalInSeconds = UPDATE_INTERVAL_PRIVATE_SKILLS_IN_SECONDS;
85                 }
86             } else {
87                 boolean isSkillDevice = false;
88                 DriverIdentity driverIdentity = shd.driverIdentity;
89                 isSkillDevice = driverIdentity != null && "SKILL".equals(driverIdentity.namespace);
90                 if (isSkillDevice) {
91                     updateIntervalInSeconds = updateIntervalSkillsInSeconds;
92                 } else {
93                     updateIntervalInSeconds = updateIntervalAmazonInSeconds;
94                 }
95             }
96         }
97         shd.updateIntervalInSeconds = updateIntervalInSeconds;
98         return updateIntervalInSeconds;
99     }
100
101     public void removeDevicesWithNoUpdate(List<SmartHomeDevice> devices) {
102         Date updateTimeStamp = new Date();
103         // check if new group is needed
104         boolean syncAllGroups = false;
105         for (SmartHomeDevice device : devices) {
106             int updateIntervalInSeconds = getUpdateIntervalInSeconds(device);
107             if (!updateGroups.containsKey(updateIntervalInSeconds)) {
108                 UpdateGroup newGroup = new UpdateGroup(updateIntervalInSeconds);
109                 updateGroups.put(updateIntervalInSeconds, newGroup);
110                 syncAllGroups = true;
111             }
112         }
113         // check which groups needs an update
114         Set<Integer> groupsToUpdate = new HashSet<Integer>();
115         for (UpdateGroup group : updateGroups.values()) {
116             long millisecondsSinceLastUpdate = updateTimeStamp.getTime() - group.lastUpdated.getTime();
117             if (syncAllGroups || millisecondsSinceLastUpdate >= group.intervalInSeconds * 1000) {
118                 group.lastUpdated = updateTimeStamp;
119                 groupsToUpdate.add(group.intervalInSeconds);
120             }
121         }
122         // remove unused devices
123         for (int i = devices.size() - 1; i >= 0; i--) {
124             if (!groupsToUpdate.contains(getUpdateIntervalInSeconds(devices.get(i)))) {
125                 devices.remove(i);
126             }
127         }
128     }
129 }