From b63e420abfd1c02b394c7f9fa5cf8caf48daaeac Mon Sep 17 00:00:00 2001 From: Dan Cunningham Date: Wed, 17 Aug 2022 01:07:04 -0700 Subject: [PATCH] [Hydrawise] concurrent error (#13268) * Fixes a concurrent modification exception, cleans up handler on dispose, fixes totally broken last contact channel Fixes #13094 Signed-off-by: Dan Cunningham --- .../org.openhab.binding.hydrawise/README.md | 2 +- .../handler/HydrawiseAccountHandler.java | 15 ++++++++++----- .../handler/HydrawiseControllerHandler.java | 19 ++++++++++++++----- .../resources/OH-INF/thing/channel-types.xml | 4 ++-- 4 files changed, 27 insertions(+), 13 deletions(-) diff --git a/bundles/org.openhab.binding.hydrawise/README.md b/bundles/org.openhab.binding.hydrawise/README.md index 33df7cb438367..2d9d17e76818e 100644 --- a/bundles/org.openhab.binding.hydrawise/README.md +++ b/bundles/org.openhab.binding.hydrawise/README.md @@ -172,7 +172,7 @@ Group SprinklerSensors "Sensors" (Sprinkler) Group SprinkerForecast "Forecast" (Sprinkler) String SprinkerControllerStatus "Status [%s]" (SprinklerController) {channel="hydrawise:controller:myaccount:123456:controller#status"} -Number SprinkerControllerLastContact "Last Contact [%d]" (SprinklerController) {channel="hydrawise:controller:myaccount:123456:controller#lastContact"} +Number SprinkerControllerLastContact "Last Contact [%d]" (SprinklerController) {channel="hydrawise:controller:myaccount:123456:controller#lastcontact"} Switch SprinklerSensor1 "Sprinler Sensor" (SprinklerSensors) {channel="hydrawise:controller:myaccount:123456:sensor1#active"} diff --git a/bundles/org.openhab.binding.hydrawise/src/main/java/org/openhab/binding/hydrawise/internal/handler/HydrawiseAccountHandler.java b/bundles/org.openhab.binding.hydrawise/src/main/java/org/openhab/binding/hydrawise/internal/handler/HydrawiseAccountHandler.java index 8aca2edfe8da4..47d7fd31964b8 100644 --- a/bundles/org.openhab.binding.hydrawise/src/main/java/org/openhab/binding/hydrawise/internal/handler/HydrawiseAccountHandler.java +++ b/bundles/org.openhab.binding.hydrawise/src/main/java/org/openhab/binding/hydrawise/internal/handler/HydrawiseAccountHandler.java @@ -66,7 +66,8 @@ public class HydrawiseAccountHandler extends BaseBridgeHandler implements Access private static final String CLIENT_SECRET = "zn3CrjglwNV1"; private static final String CLIENT_ID = "hydrawise_app"; private static final String SCOPE = "all"; - private final List controllerListeners = new ArrayList(); + private final List controllerListeners = Collections + .synchronizedList(new ArrayList()); private final HydrawiseGraphQLClient apiClient; private final OAuthClientService oAuthService; private @Nullable ScheduledFuture pollFuture; @@ -116,7 +117,9 @@ public void addControllerListeners(HydrawiseControllerListener listener) { } public void removeControllerListeners(HydrawiseControllerListener listener) { - this.controllerListeners.remove(listener); + synchronized (controllerListeners) { + this.controllerListeners.remove(listener); + } } public @Nullable HydrawiseGraphQLClient graphQLClient() { @@ -197,9 +200,11 @@ private void poll(boolean retry) { updateStatus(ThingStatus.ONLINE); } lastData = response.data.me; - controllerListeners.forEach(listener -> { - listener.onData(response.data.me.controllers); - }); + synchronized (controllerListeners) { + controllerListeners.forEach(listener -> { + listener.onData(response.data.me.controllers); + }); + } } catch (HydrawiseConnectionException e) { if (retry) { logger.debug("Retrying failed poll", e); diff --git a/bundles/org.openhab.binding.hydrawise/src/main/java/org/openhab/binding/hydrawise/internal/handler/HydrawiseControllerHandler.java b/bundles/org.openhab.binding.hydrawise/src/main/java/org/openhab/binding/hydrawise/internal/handler/HydrawiseControllerHandler.java index 087b939ba7d18..0bbd87d9ea9a1 100644 --- a/bundles/org.openhab.binding.hydrawise/src/main/java/org/openhab/binding/hydrawise/internal/handler/HydrawiseControllerHandler.java +++ b/bundles/org.openhab.binding.hydrawise/src/main/java/org/openhab/binding/hydrawise/internal/handler/HydrawiseControllerHandler.java @@ -96,11 +96,11 @@ public HydrawiseControllerHandler(Thing thing) { public void initialize() { HydrawiseControllerConfiguration config = getConfigAs(HydrawiseControllerConfiguration.class); controllerId = config.controllerId; - Bridge bridge = getBridge(); - if (bridge != null) { - HydrawiseAccountHandler handler = (HydrawiseAccountHandler) bridge.getHandler(); - if (handler != null) { - handler.addControllerListeners(this); + HydrawiseAccountHandler handler = getAccountHandler(); + if (handler != null) { + handler.addControllerListeners(this); + Bridge bridge = getBridge(); + if (bridge != null) { if (bridge.getStatus() == ThingStatus.ONLINE) { updateStatus(ThingStatus.ONLINE); } else { @@ -110,6 +110,15 @@ public void initialize() { } } + @Override + public void dispose() { + logger.debug("Controller Handler disposed."); + HydrawiseAccountHandler handler = getAccountHandler(); + if (handler != null) { + handler.removeControllerListeners(this); + } + } + @Override public void handleCommand(ChannelUID channelUID, Command command) { logger.debug("handleCommand channel {} Command {}", channelUID.getAsString(), command.toFullString()); diff --git a/bundles/org.openhab.binding.hydrawise/src/main/resources/OH-INF/thing/channel-types.xml b/bundles/org.openhab.binding.hydrawise/src/main/resources/OH-INF/thing/channel-types.xml index f6f7fddc866ff..5f54f72f7603c 100644 --- a/bundles/org.openhab.binding.hydrawise/src/main/resources/OH-INF/thing/channel-types.xml +++ b/bundles/org.openhab.binding.hydrawise/src/main/resources/OH-INF/thing/channel-types.xml @@ -68,13 +68,13 @@ - + - + DateTime Last contact time of a controller