[hue] Retrieve scenes without 10 minutes initial delay (#14289)

Fix #14137

Signed-off-by: Laurent Garnier <lg.hc@free.fr>
This commit is contained in:
lolodomo 2023-02-04 00:02:56 +01:00 committed by GitHub
parent 9deb181e1b
commit 03f17019d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -16,6 +16,7 @@ import static org.openhab.binding.hue.internal.HueBindingConstants.*;
import static org.openhab.core.thing.Thing.*; import static org.openhab.core.thing.Thing.*;
import java.io.IOException; import java.io.IOException;
import java.time.Instant;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
@ -24,6 +25,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -119,6 +121,9 @@ public class HueBridgeHandler extends ConfigStatusBridgeHandler implements HueCl
private final Map<String, SensorStatusListener> sensorStatusListeners = new ConcurrentHashMap<>(); private final Map<String, SensorStatusListener> sensorStatusListeners = new ConcurrentHashMap<>();
private final Map<String, GroupStatusListener> groupStatusListeners = new ConcurrentHashMap<>(); private final Map<String, GroupStatusListener> groupStatusListeners = new ConcurrentHashMap<>();
private List<Scene> lastScenes = new CopyOnWriteArrayList<>();
private Instant lastScenesRetrieval = Instant.MIN;
final ReentrantLock pollingLock = new ReentrantLock(); final ReentrantLock pollingLock = new ReentrantLock();
abstract class PollingRunnable implements Runnable { abstract class PollingRunnable implements Runnable {
@ -242,6 +247,10 @@ public class HueBridgeHandler extends ConfigStatusBridgeHandler implements HueCl
protected void doConnectedRun() throws IOException, ApiException { protected void doConnectedRun() throws IOException, ApiException {
updateLights(); updateLights();
updateGroups(); updateGroups();
if (lastScenesRetrieval.isBefore(Instant.now().minusSeconds(SCENE_POLLING_INTERVAL))) {
updateScenes();
lastScenesRetrieval = Instant.now();
}
} }
private void updateLights() throws IOException, ApiException { private void updateLights() throws IOException, ApiException {
@ -381,16 +390,13 @@ public class HueBridgeHandler extends ConfigStatusBridgeHandler implements HueCl
} }
}); });
} }
};
private final Runnable scenePollingRunnable = new PollingRunnable() { private void updateScenes() throws IOException, ApiException {
@Override lastScenes = hueBridge.getScenes();
protected void doConnectedRun() throws IOException, ApiException { logger.trace("Scenes detected: {}", lastScenes);
List<Scene> scenes = hueBridge.getScenes();
logger.trace("Scenes detected: {}", scenes);
setBridgeSceneChannelStateOptions(scenes, lastGroupStates); setBridgeSceneChannelStateOptions(lastScenes, lastGroupStates);
notifyGroupSceneUpdate(scenes); notifyGroupSceneUpdate(lastScenes);
} }
private void setBridgeSceneChannelStateOptions(List<Scene> scenes, Map<String, FullGroup> groups) { private void setBridgeSceneChannelStateOptions(List<Scene> scenes, Map<String, FullGroup> groups) {
@ -412,7 +418,6 @@ public class HueBridgeHandler extends ConfigStatusBridgeHandler implements HueCl
private @Nullable Future<?> initJob; private @Nullable Future<?> initJob;
private @Nullable ScheduledFuture<?> lightPollingJob; private @Nullable ScheduledFuture<?> lightPollingJob;
private @Nullable ScheduledFuture<?> sensorPollingJob; private @Nullable ScheduledFuture<?> sensorPollingJob;
private @Nullable ScheduledFuture<?> scenePollingJob;
private @NonNullByDefault({}) HueBridge hueBridge = null; private @NonNullByDefault({}) HueBridge hueBridge = null;
private @NonNullByDefault({}) HueBridgeConfig hueBridgeConfig = null; private @NonNullByDefault({}) HueBridgeConfig hueBridgeConfig = null;
@ -660,23 +665,6 @@ public class HueBridgeHandler extends ConfigStatusBridgeHandler implements HueCl
sensorPollingJob = null; sensorPollingJob = null;
} }
private void startScenePolling() {
ScheduledFuture<?> job = scenePollingJob;
if (job == null || job.isCancelled()) {
// Delay the first execution to give a chance to have all group things registered
scenePollingJob = scheduler.scheduleWithFixedDelay(scenePollingRunnable, 5, SCENE_POLLING_INTERVAL,
TimeUnit.SECONDS);
}
}
private void stopScenePolling() {
ScheduledFuture<?> job = scenePollingJob;
if (job != null) {
job.cancel(true);
}
scenePollingJob = null;
}
@Override @Override
public void dispose() { public void dispose() {
logger.debug("Disposing Hue Bridge handler ..."); logger.debug("Disposing Hue Bridge handler ...");
@ -686,7 +674,6 @@ public class HueBridgeHandler extends ConfigStatusBridgeHandler implements HueCl
} }
stopLightPolling(); stopLightPolling();
stopSensorPolling(); stopSensorPolling();
stopScenePolling();
if (hueBridge != null) { if (hueBridge != null) {
hueBridge = null; hueBridge = null;
} }
@ -749,7 +736,6 @@ public class HueBridgeHandler extends ConfigStatusBridgeHandler implements HueCl
private synchronized void onUpdate() { private synchronized void onUpdate() {
startLightPolling(); startLightPolling();
startSensorPolling(); startSensorPolling();
startScenePolling();
} }
/** /**
@ -967,6 +953,9 @@ public class HueBridgeHandler extends ConfigStatusBridgeHandler implements HueCl
final FullGroup lastGroupState = lastGroupStates.get(groupId); final FullGroup lastGroupState = lastGroupStates.get(groupId);
if (lastGroupState != null) { if (lastGroupState != null) {
groupStatusListener.onGroupAdded(lastGroupState); groupStatusListener.onGroupAdded(lastGroupState);
if (!lastScenes.isEmpty()) {
groupStatusListener.onScenesUpdated(lastScenes);
}
} }
return true; return true;
} }