From ba9d8b3edba464320e1d49e7c4faeee2c2745281 Mon Sep 17 00:00:00 2001 From: Jan Gustafsson Date: Sun, 31 Oct 2021 21:45:36 +0100 Subject: [PATCH] [verisure] Keep refreshing after RuntimeException (#11397) * Fix that binding stops refreshing after RuntimException (#11396) Signed-off-by: Jan Gustafsson * Updated after review comments Signed-off-by: Jan Gustafsson --- .../verisure/internal/VerisureSession.java | 228 +++++++++--------- .../internal/dto/VerisureBaseThingDTO.java | 12 +- .../handler/VerisureBridgeHandler.java | 39 ++- 3 files changed, 140 insertions(+), 139 deletions(-) diff --git a/bundles/org.openhab.binding.verisure/src/main/java/org/openhab/binding/verisure/internal/VerisureSession.java b/bundles/org.openhab.binding.verisure/src/main/java/org/openhab/binding/verisure/internal/VerisureSession.java index da5542307c980..709e3fbc2529c 100644 --- a/bundles/org.openhab.binding.verisure/src/main/java/org/openhab/binding/verisure/internal/VerisureSession.java +++ b/bundles/org.openhab.binding.verisure/src/main/java/org/openhab/binding/verisure/internal/VerisureSession.java @@ -109,7 +109,7 @@ public VerisureSession(HttpClient httpClient) { public boolean initialize(@Nullable String authstring, @Nullable String pinCode, String userName, String password) { if (authstring != null) { - this.authstring = authstring.substring(0); + this.authstring = authstring; this.pinCode = pinCode; this.userName = userName; this.password = password; @@ -124,17 +124,12 @@ public boolean initialize(@Nullable String authstring, @Nullable String pinCode, } public boolean refresh() { - try { - if (logIn()) { - if (updateStatus()) { - return true; - } + if (logIn()) { + if (updateStatus()) { + return true; } - return false; - } catch (HttpResponseException e) { - logger.warn("Failed to do a refresh {}", e.getMessage()); - return false; } + return false; } public int sendCommand(String url, String data, BigDecimal installationId) { @@ -550,7 +545,8 @@ private synchronized boolean logIn() { } else { return true; } - } catch (ExecutionException | InterruptedException | TimeoutException | URISyntaxException e) { + } catch (ExecutionException | InterruptedException | TimeoutException | URISyntaxException + | HttpResponseException e) { logger.warn("Failed to login {}", e.getMessage()); } return false; @@ -654,33 +650,34 @@ private synchronized void updateSmartLockStatus(VerisureInstallation installatio VerisureSmartLocksDTO thing = postJSONVerisureAPI(url, queryQLSmartLock, VerisureSmartLocksDTO.class); logger.debug("REST Response ({})", thing); List doorLockList = thing.getData().getInstallation().getDoorlocks(); - doorLockList.forEach(doorLock -> { - VerisureSmartLocksDTO slThing = new VerisureSmartLocksDTO(); - VerisureSmartLocksDTO.Installation inst = new VerisureSmartLocksDTO.Installation(); - inst.setDoorlocks(Collections.singletonList(doorLock)); - VerisureSmartLocksDTO.Data data = new VerisureSmartLocksDTO.Data(); - data.setInstallation(inst); - slThing.setData(data); - // Set unique deviceID - String deviceId = doorLock.getDevice().getDeviceLabel(); - if (deviceId != null) { - // Set location - slThing.setLocation(doorLock.getDevice().getArea()); - slThing.setDeviceId(deviceId); - - // Fetch more info from old endpoint - try { - VerisureSmartLockDTO smartLockThing = getJSONVerisureAPI(SMARTLOCK_PATH + slThing.getDeviceId(), - VerisureSmartLockDTO.class); - logger.debug("REST Response ({})", smartLockThing); - slThing.setSmartLockJSON(smartLockThing); - } catch (ExecutionException | InterruptedException | TimeoutException | JsonSyntaxException e) { - logger.warn("Failed to query for smartlock status: {}", e.getMessage()); - } - notifyListenersIfChanged(slThing, installation, deviceId); - } - }); + if (doorLockList != null) { + doorLockList.forEach(doorLock -> { + VerisureSmartLocksDTO slThing = new VerisureSmartLocksDTO(); + VerisureSmartLocksDTO.Installation inst = new VerisureSmartLocksDTO.Installation(); + inst.setDoorlocks(Collections.singletonList(doorLock)); + VerisureSmartLocksDTO.Data data = new VerisureSmartLocksDTO.Data(); + data.setInstallation(inst); + slThing.setData(data); + // Set unique deviceID + String deviceId = doorLock.getDevice().getDeviceLabel(); + if (deviceId != null) { + // Set location + slThing.setLocation(doorLock.getDevice().getArea()); + slThing.setDeviceId(deviceId); + // Fetch more info from old endpoint + try { + VerisureSmartLockDTO smartLockThing = getJSONVerisureAPI( + SMARTLOCK_PATH + slThing.getDeviceId(), VerisureSmartLockDTO.class); + logger.debug("REST Response ({})", smartLockThing); + slThing.setSmartLockJSON(smartLockThing); + } catch (ExecutionException | InterruptedException | TimeoutException | JsonSyntaxException e) { + logger.warn("Failed to query for smartlock status: {}", e.getMessage()); + } + notifyListenersIfChanged(slThing, installation, deviceId); + } + }); + } } catch (ExecutionException | InterruptedException | TimeoutException | JsonSyntaxException | PostToAPIException e) { logger.warn("Failed to send a POST to the API {}", e.getMessage()); @@ -702,21 +699,23 @@ private synchronized void updateSmartPlugStatus(VerisureInstallation installatio VerisureSmartPlugsDTO thing = postJSONVerisureAPI(url, queryQLSmartPlug, VerisureSmartPlugsDTO.class); logger.debug("REST Response ({})", thing); List smartPlugList = thing.getData().getInstallation().getSmartplugs(); - smartPlugList.forEach(smartPlug -> { - VerisureSmartPlugsDTO spThing = new VerisureSmartPlugsDTO(); - VerisureSmartPlugsDTO.Installation inst = new VerisureSmartPlugsDTO.Installation(); - inst.setSmartplugs(Collections.singletonList(smartPlug)); - VerisureSmartPlugsDTO.Data data = new VerisureSmartPlugsDTO.Data(); - data.setInstallation(inst); - spThing.setData(data); - // Set unique deviceID - String deviceId = smartPlug.getDevice().getDeviceLabel(); - if (deviceId != null) { - // Set location - spThing.setLocation(smartPlug.getDevice().getArea()); - notifyListenersIfChanged(spThing, installation, deviceId); - } - }); + if (smartPlugList != null) { + smartPlugList.forEach(smartPlug -> { + VerisureSmartPlugsDTO spThing = new VerisureSmartPlugsDTO(); + VerisureSmartPlugsDTO.Installation inst = new VerisureSmartPlugsDTO.Installation(); + inst.setSmartplugs(Collections.singletonList(smartPlug)); + VerisureSmartPlugsDTO.Data data = new VerisureSmartPlugsDTO.Data(); + data.setInstallation(inst); + spThing.setData(data); + // Set unique deviceID + String deviceId = smartPlug.getDevice().getDeviceLabel(); + if (deviceId != null) { + // Set location + spThing.setLocation(smartPlug.getDevice().getArea()); + notifyListenersIfChanged(spThing, installation, deviceId); + } + }); + } } catch (ExecutionException | InterruptedException | TimeoutException | JsonSyntaxException | PostToAPIException e) { logger.warn("Failed to send a POST to the API {}", e.getMessage()); @@ -821,32 +820,35 @@ private synchronized void updateDoorWindowStatus(VerisureInstallation installati VerisureDoorWindowsDTO thing = postJSONVerisureAPI(url, queryQLDoorWindow, VerisureDoorWindowsDTO.class); logger.debug("REST Response ({})", thing); List doorWindowList = thing.getData().getInstallation().getDoorWindows(); - doorWindowList.forEach(doorWindow -> { - VerisureDoorWindowsDTO dThing = new VerisureDoorWindowsDTO(); - VerisureDoorWindowsDTO.Installation inst = new VerisureDoorWindowsDTO.Installation(); - inst.setDoorWindows(Collections.singletonList(doorWindow)); - VerisureDoorWindowsDTO.Data data = new VerisureDoorWindowsDTO.Data(); - data.setInstallation(inst); - dThing.setData(data); - // Set unique deviceID - String deviceId = doorWindow.getDevice().getDeviceLabel(); - if (deviceId != null) { - try { - VerisureBatteryStatusDTO[] batteryStatusThingArray = getJSONVerisureAPI(BATTERY_STATUS, - VerisureBatteryStatusDTO[].class); - VerisureBatteryStatusDTO batteryStatus = getBatteryStatus(deviceId, batteryStatusThingArray); - if (batteryStatus != null) { - logger.debug("REST Response ({})", batteryStatus); - dThing.setBatteryStatus(batteryStatus); + if (doorWindowList != null) { + doorWindowList.forEach(doorWindow -> { + VerisureDoorWindowsDTO dThing = new VerisureDoorWindowsDTO(); + VerisureDoorWindowsDTO.Installation inst = new VerisureDoorWindowsDTO.Installation(); + inst.setDoorWindows(Collections.singletonList(doorWindow)); + VerisureDoorWindowsDTO.Data data = new VerisureDoorWindowsDTO.Data(); + data.setInstallation(inst); + dThing.setData(data); + // Set unique deviceID + String deviceId = doorWindow.getDevice().getDeviceLabel(); + if (deviceId != null) { + try { + VerisureBatteryStatusDTO[] batteryStatusThingArray = getJSONVerisureAPI(BATTERY_STATUS, + VerisureBatteryStatusDTO[].class); + VerisureBatteryStatusDTO batteryStatus = getBatteryStatus(deviceId, + batteryStatusThingArray); + if (batteryStatus != null) { + logger.debug("REST Response ({})", batteryStatus); + dThing.setBatteryStatus(batteryStatus); + } + } catch (ExecutionException | InterruptedException | TimeoutException | JsonSyntaxException e) { + logger.warn("Failed to query for door&window status: {}", e.getMessage()); } - } catch (ExecutionException | InterruptedException | TimeoutException | JsonSyntaxException e) { - logger.warn("Failed to query for door&window status: {}", e.getMessage()); + // Set location + dThing.setLocation(doorWindow.getDevice().getArea()); + notifyListenersIfChanged(dThing, installation, deviceId); } - // Set location - dThing.setLocation(doorWindow.getDevice().getArea()); - notifyListenersIfChanged(dThing, installation, deviceId); - } - }); + }); + } } catch (ExecutionException | InterruptedException | TimeoutException | JsonSyntaxException | PostToAPIException e) { logger.warn("Failed to send a POST to the API {}", e.getMessage()); @@ -896,20 +898,22 @@ private synchronized void updateUserPresenceStatus(VerisureInstallation installa logger.debug("REST Response ({})", thing); List userTrackingList = thing.getData().getInstallation() .getUserTrackings(); - userTrackingList.forEach(userTracking -> { - String localUserTrackingStatus = userTracking.getStatus(); - if ("ACTIVE".equals(localUserTrackingStatus)) { - VerisureUserPresencesDTO upThing = new VerisureUserPresencesDTO(); - VerisureUserPresencesDTO.Installation inst = new VerisureUserPresencesDTO.Installation(); - inst.setUserTrackings(Collections.singletonList(userTracking)); - VerisureUserPresencesDTO.Data data = new VerisureUserPresencesDTO.Data(); - data.setInstallation(inst); - upThing.setData(data); - // Set unique deviceID - String deviceId = "up" + userTracking.getWebAccount() + installationId; - notifyListenersIfChanged(upThing, installation, deviceId); - } - }); + if (userTrackingList != null) { + userTrackingList.forEach(userTracking -> { + String localUserTrackingStatus = userTracking.getStatus(); + if ("ACTIVE".equals(localUserTrackingStatus)) { + VerisureUserPresencesDTO upThing = new VerisureUserPresencesDTO(); + VerisureUserPresencesDTO.Installation inst = new VerisureUserPresencesDTO.Installation(); + inst.setUserTrackings(Collections.singletonList(userTracking)); + VerisureUserPresencesDTO.Data data = new VerisureUserPresencesDTO.Data(); + data.setInstallation(inst); + upThing.setData(data); + // Set unique deviceID + String deviceId = "up" + userTracking.getWebAccount() + installationId; + notifyListenersIfChanged(upThing, installation, deviceId); + } + }); + } } catch (ExecutionException | InterruptedException | TimeoutException | JsonSyntaxException | PostToAPIException e) { logger.warn("Failed to send a POST to the API {}", e.getMessage()); @@ -933,22 +937,24 @@ private synchronized void updateMiceDetectionStatus(VerisureInstallation install VerisureMiceDetectionDTO.class); logger.debug("REST Response ({})", thing); List miceList = thing.getData().getInstallation().getMice(); - miceList.forEach(mouse -> { - VerisureMiceDetectionDTO miceThing = new VerisureMiceDetectionDTO(); - VerisureMiceDetectionDTO.Installation inst = new VerisureMiceDetectionDTO.Installation(); - inst.setMice(Collections.singletonList(mouse)); - VerisureMiceDetectionDTO.Data data = new VerisureMiceDetectionDTO.Data(); - data.setInstallation(inst); - miceThing.setData(data); - // Set unique deviceID - String deviceId = mouse.getDevice().getDeviceLabel(); - logger.debug("Mouse id: {} for thing: {}", deviceId, mouse); - if (deviceId != null) { - // Set location - miceThing.setLocation(mouse.getDevice().getArea()); - notifyListenersIfChanged(miceThing, installation, deviceId); - } - }); + if (miceList != null) { + miceList.forEach(mouse -> { + VerisureMiceDetectionDTO miceThing = new VerisureMiceDetectionDTO(); + VerisureMiceDetectionDTO.Installation inst = new VerisureMiceDetectionDTO.Installation(); + inst.setMice(Collections.singletonList(mouse)); + VerisureMiceDetectionDTO.Data data = new VerisureMiceDetectionDTO.Data(); + data.setInstallation(inst); + miceThing.setData(data); + // Set unique deviceID + String deviceId = mouse.getDevice().getDeviceLabel(); + logger.debug("Mouse id: {} for thing: {}", deviceId, mouse); + if (deviceId != null) { + // Set location + miceThing.setLocation(mouse.getDevice().getArea()); + notifyListenersIfChanged(miceThing, installation, deviceId); + } + }); + } } catch (ExecutionException | InterruptedException | TimeoutException | JsonSyntaxException | PostToAPIException e) { logger.warn("Failed to send a POST to the API {}", e.getMessage()); @@ -1006,10 +1012,12 @@ private synchronized void updateGatewayStatus(VerisureInstallation installation) logger.debug("REST Response ({})", thing); // Set unique deviceID List communicationStateList = thing.getData().getInstallation().getCommunicationState(); - if (!communicationStateList.isEmpty()) { - String deviceId = communicationStateList.get(0).getDevice().getDeviceLabel(); - if (deviceId != null) { - notifyListenersIfChanged(thing, installation, deviceId); + if (communicationStateList != null) { + if (!communicationStateList.isEmpty()) { + String deviceId = communicationStateList.get(0).getDevice().getDeviceLabel(); + if (deviceId != null) { + notifyListenersIfChanged(thing, installation, deviceId); + } } } } catch (ExecutionException | InterruptedException | TimeoutException | JsonSyntaxException diff --git a/bundles/org.openhab.binding.verisure/src/main/java/org/openhab/binding/verisure/internal/dto/VerisureBaseThingDTO.java b/bundles/org.openhab.binding.verisure/src/main/java/org/openhab/binding/verisure/internal/dto/VerisureBaseThingDTO.java index 39b63731c21d7..923ad0fac66fe 100644 --- a/bundles/org.openhab.binding.verisure/src/main/java/org/openhab/binding/verisure/internal/dto/VerisureBaseThingDTO.java +++ b/bundles/org.openhab.binding.verisure/src/main/java/org/openhab/binding/verisure/internal/dto/VerisureBaseThingDTO.java @@ -272,7 +272,7 @@ public void setClimates(List climates) { this.climates = climates; } - public List getDoorWindows() { + public @Nullable List getDoorWindows() { return doorWindows; } @@ -284,11 +284,11 @@ public EventLog getEventLog() { return eventLog; } - public List getCommunicationState() { + public @Nullable List getCommunicationState() { return communicationState; } - public List getMice() { + public @Nullable List getMice() { return mice; } @@ -296,7 +296,7 @@ public void setMice(List mice) { this.mice = mice; } - public List getDoorlocks() { + public @Nullable List getDoorlocks() { return doorlocks; } @@ -304,7 +304,7 @@ public void setDoorlocks(List doorlocks) { this.doorlocks = doorlocks; } - public List getSmartplugs() { + public @Nullable List getSmartplugs() { return smartplugs; } @@ -312,7 +312,7 @@ public void setSmartplugs(List smartplugs) { this.smartplugs = smartplugs; } - public List getUserTrackings() { + public @Nullable List getUserTrackings() { return userTrackings; } diff --git a/bundles/org.openhab.binding.verisure/src/main/java/org/openhab/binding/verisure/internal/handler/VerisureBridgeHandler.java b/bundles/org.openhab.binding.verisure/src/main/java/org/openhab/binding/verisure/internal/handler/VerisureBridgeHandler.java index bfaa0e664e650..94017d900798f 100644 --- a/bundles/org.openhab.binding.verisure/src/main/java/org/openhab/binding/verisure/internal/handler/VerisureBridgeHandler.java +++ b/bundles/org.openhab.binding.verisure/src/main/java/org/openhab/binding/verisure/internal/handler/VerisureBridgeHandler.java @@ -110,28 +110,22 @@ public void initialize() { updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Refresh time is lower than min value of 10!"); } else { - try { - authstring = "j_username=" + config.username; - scheduler.execute(() -> { - if (session == null) { - logger.debug("Session is null, let's create a new one"); - session = new VerisureSession(this.httpClient); - } - VerisureSession session = this.session; - updateStatus(ThingStatus.UNKNOWN); - if (session != null) { - if (!session.initialize(authstring, pinCode, config.username, config.password)) { - updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.HANDLER_REGISTERING_ERROR, - "Failed to login to Verisure, please check your account settings! Is MFA activated?"); - return; - } - startAutomaticRefresh(config.refresh); + authstring = "j_username=" + config.username; + scheduler.execute(() -> { + if (session == null) { + logger.debug("Session is null, let's create a new one"); + session = new VerisureSession(this.httpClient); + } + VerisureSession session = this.session; + updateStatus(ThingStatus.UNKNOWN); + if (session != null) { + if (!session.initialize(authstring, pinCode, config.username, config.password)) { + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, + "Failed to login to Verisure, please check your account settings! Is MFA activated?"); } - }); - } catch (RuntimeException e) { - logger.warn("Failed to initialize: {}", e.getMessage()); - updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage()); - } + } + startAutomaticRefresh(config.refresh); + }); } } @@ -172,8 +166,7 @@ private void refreshAndUpdateStatus() { logger.debug("Refresh and update status!"); VerisureSession session = this.session; if (session != null) { - boolean success = session.refresh(); - if (success) { + if (session.refresh()) { updateStatus(ThingStatus.ONLINE); } else { updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);