2 * Copyright (c) 2010-2024 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.eclipse.jdt.annotation.NonNullByDefault;
23 import org.openhab.binding.amazonechocontrol.internal.jsons.JsonSmartHomeDevices.DriverIdentity;
24 import org.openhab.binding.amazonechocontrol.internal.jsons.JsonSmartHomeDevices.SmartHomeDevice;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
29 * Handles the update interval calculation
31 * @author Michael Geramb - Initial contribution
34 public class SmartHomeDeviceStateGroupUpdateCalculator {
35 private final Logger logger = LoggerFactory.getLogger(SmartHomeDeviceStateGroupUpdateCalculator.class);
37 private static final Integer UPDATE_INTERVAL_PRIVATE_SKILLS_IN_SECONDS = 600;
38 private static final Integer UPDATE_INTERVAL_PRIVATE_SKILLS_IN_SECONDS_TRACE = 10;
39 private static final Integer UPDATE_INTERVAL_ACOUSTIC_EVENTS_IN_SECONDS = 10;
40 private Integer updateIntervalAmazonInSeconds;
41 private Integer updateIntervalSkillsInSeconds;
43 private static class UpdateGroup {
44 private final int intervalInSeconds;
45 private Date lastUpdated;
47 public UpdateGroup(int intervalInSeconds) {
48 this.intervalInSeconds = intervalInSeconds;
49 this.lastUpdated = new Date(0);
53 private final Map<Integer, UpdateGroup> updateGroups = new HashMap<>();
55 public SmartHomeDeviceStateGroupUpdateCalculator(int updateIntervalAmazonInSeconds,
56 int updateIntervalSkillsInSeconds) {
57 this.updateIntervalAmazonInSeconds = updateIntervalAmazonInSeconds;
58 this.updateIntervalSkillsInSeconds = updateIntervalSkillsInSeconds;
61 private Integer getUpdateIntervalInSeconds(SmartHomeDevice shd) {
62 Integer updateIntervalInSeconds = shd.updateIntervalInSeconds;
63 if (updateIntervalInSeconds != null) {
64 return updateIntervalInSeconds;
66 if (shd.getCapabilities().stream()
67 .anyMatch(capability -> HandlerAcousticEventSensor.INTERFACE.equals(capability.interfaceName))) {
68 updateIntervalInSeconds = UPDATE_INTERVAL_ACOUSTIC_EVENTS_IN_SECONDS;
71 if (updateIntervalInSeconds == null) {
72 String manufacturerName = shd.manufacturerName;
73 if (manufacturerName != null && ("openHAB".equalsIgnoreCase(manufacturerName)
74 || manufacturerName.toLowerCase().startsWith("iobroker"))) {
75 // OpenHAB or ioBroker skill
76 if (logger.isTraceEnabled()) {
77 updateIntervalInSeconds = UPDATE_INTERVAL_PRIVATE_SKILLS_IN_SECONDS_TRACE;
79 updateIntervalInSeconds = UPDATE_INTERVAL_PRIVATE_SKILLS_IN_SECONDS;
82 boolean isSkillDevice = false;
83 DriverIdentity driverIdentity = shd.driverIdentity;
84 isSkillDevice = driverIdentity != null && "SKILL".equals(driverIdentity.namespace);
86 updateIntervalInSeconds = updateIntervalSkillsInSeconds;
88 updateIntervalInSeconds = updateIntervalAmazonInSeconds;
92 shd.updateIntervalInSeconds = updateIntervalInSeconds;
93 return updateIntervalInSeconds;
96 public void removeDevicesWithNoUpdate(List<SmartHomeDevice> devices) {
97 Date updateTimeStamp = new Date();
98 // check if new group is needed
99 boolean syncAllGroups = false;
100 for (SmartHomeDevice device : devices) {
101 int updateIntervalInSeconds = getUpdateIntervalInSeconds(device);
102 if (!updateGroups.containsKey(updateIntervalInSeconds)) {
103 UpdateGroup newGroup = new UpdateGroup(updateIntervalInSeconds);
104 updateGroups.put(updateIntervalInSeconds, newGroup);
105 syncAllGroups = true;
108 // check which groups needs an update
109 Set<Integer> groupsToUpdate = new HashSet<Integer>();
110 for (UpdateGroup group : updateGroups.values()) {
111 long millisecondsSinceLastUpdate = updateTimeStamp.getTime() - group.lastUpdated.getTime();
112 if (syncAllGroups || millisecondsSinceLastUpdate >= group.intervalInSeconds * 1000) {
113 group.lastUpdated = updateTimeStamp;
114 groupsToUpdate.add(group.intervalInSeconds);
117 // remove unused devices
118 for (int i = devices.size() - 1; i >= 0; i--) {
119 if (!groupsToUpdate.contains(getUpdateIntervalInSeconds(devices.get(i)))) {