diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewHubHandler.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewHubHandler.java index ebe36df33..3f6d17475 100644 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewHubHandler.java +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewHubHandler.java @@ -17,6 +17,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; @@ -57,6 +58,7 @@ import org.openhab.core.thing.ChannelUID; import org.openhab.core.thing.Thing; import org.openhab.core.thing.ThingStatus; import org.openhab.core.thing.ThingStatusDetail; +import org.openhab.core.thing.ThingUID; import org.openhab.core.thing.binding.BaseBridgeHandler; import org.openhab.core.thing.binding.ThingHandler; import org.openhab.core.thing.binding.builder.ChannelBuilder; @@ -77,11 +79,10 @@ import org.slf4j.LoggerFactory; @NonNullByDefault public class HDPowerViewHubHandler extends BaseBridgeHandler { - private static final long INITIAL_SOFT_POLL_DELAY_MS = 5_000; - private final Logger logger = LoggerFactory.getLogger(HDPowerViewHubHandler.class); private final HttpClient httpClient; private final HDPowerViewTranslationProvider translationProvider; + private final ConcurrentHashMap pendingShadeInitializations = new ConcurrentHashMap<>(); private long refreshInterval; private long hardRefreshPositionInterval; @@ -135,11 +136,11 @@ public class HDPowerViewHubHandler extends BaseBridgeHandler { if (sceneChannelTypeUID.equals(channel.getChannelTypeUID()) && OnOffType.ON == command) { webTargets.activateScene(id); // Reschedule soft poll for immediate shade position update. - scheduleSoftPoll(0); + scheduleSoftPoll(); } else if (sceneGroupChannelTypeUID.equals(channel.getChannelTypeUID()) && OnOffType.ON == command) { webTargets.activateSceneCollection(id); // Reschedule soft poll for immediate shade position update. - scheduleSoftPoll(0); + scheduleSoftPoll(); } else if (automationChannelTypeUID.equals(channel.getChannelTypeUID())) { webTargets.enableScheduledEvent(id, OnOffType.ON == command); } @@ -162,6 +163,7 @@ public class HDPowerViewHubHandler extends BaseBridgeHandler { return; } + pendingShadeInitializations.clear(); webTargets = new HDPowerViewWebTargets(httpClient, host); refreshInterval = config.refresh; hardRefreshPositionInterval = config.hardRefresh; @@ -193,21 +195,42 @@ public class HDPowerViewHubHandler extends BaseBridgeHandler { public void dispose() { super.dispose(); stopPoll(); + pendingShadeInitializations.clear(); + } + + @Override + public void childHandlerInitialized(final ThingHandler childHandler, final Thing childThing) { + logger.debug("Child handler initialized: {}", childThing.getUID()); + if (childHandler instanceof HDPowerViewShadeHandler) { + ShadeData shadeData = pendingShadeInitializations.remove(childThing.getUID()); + if (shadeData != null) { + updateShadeThing(shadeData.id, childThing, shadeData); + } + } + super.childHandlerInitialized(childHandler, childThing); + } + + @Override + public void childHandlerDisposed(ThingHandler childHandler, Thing childThing) { + logger.debug("Child handler disposed: {}", childThing.getUID()); + if (childHandler instanceof HDPowerViewShadeHandler) { + pendingShadeInitializations.remove(childThing.getUID()); + } + super.childHandlerDisposed(childHandler, childThing); } private void schedulePoll() { - scheduleSoftPoll(INITIAL_SOFT_POLL_DELAY_MS); + scheduleSoftPoll(); scheduleHardPoll(); } - private void scheduleSoftPoll(long initialDelay) { + private void scheduleSoftPoll() { ScheduledFuture future = this.pollFuture; if (future != null) { future.cancel(false); } - logger.debug("Scheduling poll for {} ms out, then every {} ms", initialDelay, refreshInterval); - this.pollFuture = scheduler.scheduleWithFixedDelay(this::poll, initialDelay, refreshInterval, - TimeUnit.MILLISECONDS); + logger.debug("Scheduling poll every {} ms", refreshInterval); + this.pollFuture = scheduler.scheduleWithFixedDelay(this::poll, 0, refreshInterval, TimeUnit.MILLISECONDS); } private void scheduleHardPoll() { @@ -336,17 +359,35 @@ public class HDPowerViewHubHandler extends BaseBridgeHandler { } private void updateShadeThing(int shadeId, Thing thing, @Nullable ShadeData shadeData) { + if (shadeData == null) { + logger.debug("Shade '{}' has no data in hub", shadeId); + return; + } HDPowerViewShadeHandler thingHandler = ((HDPowerViewShadeHandler) thing.getHandler()); if (thingHandler == null) { logger.debug("Shade '{}' handler not initialized", shadeId); + pendingShadeInitializations.put(thing.getUID(), shadeData); return; } - if (shadeData == null) { - logger.debug("Shade '{}' has no data in hub", shadeId); - } else { - logger.debug("Updating shade '{}'", shadeId); + ThingStatus thingStatus = thingHandler.getThing().getStatus(); + switch (thingStatus) { + case UNKNOWN: + case ONLINE: + case OFFLINE: + logger.debug("Updating shade '{}'", shadeId); + thingHandler.onReceiveUpdate(shadeData); + break; + case UNINITIALIZED: + case INITIALIZING: + logger.debug("Shade '{}' handler not yet ready; status: {}", shadeId, thingStatus); + pendingShadeInitializations.put(thing.getUID(), shadeData); + break; + case REMOVING: + case REMOVED: + default: + logger.debug("Ignoring shade update for shade '{}' in status {}", shadeId, thingStatus); + break; } - thingHandler.onReceiveUpdate(shadeData); } private List fetchScenes() diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewShadeHandler.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewShadeHandler.java index b8bc47773..701cf4805 100644 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewShadeHandler.java +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/handler/HDPowerViewShadeHandler.java @@ -107,12 +107,7 @@ public class HDPowerViewShadeHandler extends AbstractHubbedThingHandler { "@text/offline.conf-error.invalid-bridge-handler"); return; } - ThingStatus bridgeStatus = bridge.getStatus(); - if (bridgeStatus == ThingStatus.ONLINE) { - updateStatus(ThingStatus.UNKNOWN); - } else { - updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE); - } + updateStatus(ThingStatus.UNKNOWN); } @Override