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.amazonechocontrol.internal.smarthome;
15 import java.util.Date;
16 import java.util.HashMap;
17 import java.util.HashSet;
18 import java.util.List;
22 import org.apache.commons.lang.StringUtils;
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.openhab.binding.amazonechocontrol.internal.jsons.JsonSmartHomeCapabilities.SmartHomeCapability;
25 import org.openhab.binding.amazonechocontrol.internal.jsons.JsonSmartHomeDevices.DriverIdentity;
26 import org.openhab.binding.amazonechocontrol.internal.jsons.JsonSmartHomeDevices.SmartHomeDevice;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
31 * Handles the update interval calculation
33 * @author Michael Geramb - Initial contribution
36 public class SmartHomeDeviceStateGroupUpdateCalculator {
37 private final Logger logger = LoggerFactory.getLogger(SmartHomeDeviceStateGroupUpdateCalculator.class);
39 private static final Integer UPDATE_INTERVAL_PRIVATE_SKILLS_IN_SECONDS = 10;
40 private static final Integer UPDATE_INTERVAL_PRIVATE_SKILLS_IN_SECONDS_TRACE = 600;
41 private static final Integer UPDATE_INTERVAL_ACOUSTIC_EVENTS_IN_SECONDS = 10;
42 private Integer updateIntervalAmazonInSeconds;
43 private Integer updateIntervalSkillsInSeconds;
45 private static class UpdateGroup {
46 private final int intervalInSeconds;
47 private Date lastUpdated;
49 public UpdateGroup(int intervalInSeconds) {
50 this.intervalInSeconds = intervalInSeconds;
51 this.lastUpdated = new Date(0);
55 private final Map<Integer, UpdateGroup> updateGroups = new HashMap<>();
57 public SmartHomeDeviceStateGroupUpdateCalculator(int updateIntervalAmazonInSeconds,
58 int updateIntervalSkillsInSeconds) {
59 this.updateIntervalAmazonInSeconds = updateIntervalAmazonInSeconds;
60 this.updateIntervalSkillsInSeconds = updateIntervalSkillsInSeconds;
63 private Integer getUpdateIntervalInSeconds(SmartHomeDevice shd) {
64 Integer updateIntervalInSeconds = shd.updateIntervalInSeconds;
65 if (updateIntervalInSeconds != null) {
66 return updateIntervalInSeconds;
68 SmartHomeCapability[] capabilities = shd.capabilities;
69 if (capabilities != null) {
70 for (SmartHomeCapability capability : capabilities) {
71 if (capability != null && HandlerAcousticEventSensor.INTERFACE.equals(capability.interfaceName)) {
72 updateIntervalInSeconds = UPDATE_INTERVAL_ACOUSTIC_EVENTS_IN_SECONDS;
77 if (updateIntervalInSeconds == null) {
78 if ("openHAB".equalsIgnoreCase(shd.manufacturerName)
79 || StringUtils.startsWithIgnoreCase(shd.manufacturerName, "ioBroker")) {
80 // OpenHAB or ioBroker skill
81 if (logger.isTraceEnabled()) {
82 updateIntervalInSeconds = UPDATE_INTERVAL_PRIVATE_SKILLS_IN_SECONDS_TRACE;
84 updateIntervalInSeconds = UPDATE_INTERVAL_PRIVATE_SKILLS_IN_SECONDS;
87 boolean isSkillDevice = false;
88 DriverIdentity driverIdentity = shd.driverIdentity;
89 isSkillDevice = driverIdentity != null && "SKILL".equals(driverIdentity.namespace);
91 updateIntervalInSeconds = updateIntervalSkillsInSeconds;
93 updateIntervalInSeconds = updateIntervalAmazonInSeconds;
97 shd.updateIntervalInSeconds = updateIntervalInSeconds;
98 return updateIntervalInSeconds;
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;
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);
122 // remove unused devices
123 for (int i = devices.size() - 1; i >= 0; i--) {
124 if (!groupsToUpdate.contains(getUpdateIntervalInSeconds(devices.get(i)))) {