]> git.basschouten.com Git - openhab-addons.git/commitdiff
[myq] Fixes breaking API changes to the MyQ binding (#11601)
authorDan Cunningham <dan@digitaldan.com>
Fri, 19 Nov 2021 23:17:27 +0000 (15:17 -0800)
committerGitHub <noreply@github.com>
Fri, 19 Nov 2021 23:17:27 +0000 (00:17 +0100)
Signed-off-by: Dan Cunningham <dan@digitaldan.com>
14 files changed:
bundles/org.openhab.binding.myq/src/main/java/org/openhab/binding/myq/internal/MyQDiscoveryService.java
bundles/org.openhab.binding.myq/src/main/java/org/openhab/binding/myq/internal/dto/AccountDTO.java
bundles/org.openhab.binding.myq/src/main/java/org/openhab/binding/myq/internal/dto/AccountInfoDTO.java [deleted file]
bundles/org.openhab.binding.myq/src/main/java/org/openhab/binding/myq/internal/dto/AccountsDTO.java [new file with mode: 0644]
bundles/org.openhab.binding.myq/src/main/java/org/openhab/binding/myq/internal/dto/ActionDTO.java [deleted file]
bundles/org.openhab.binding.myq/src/main/java/org/openhab/binding/myq/internal/dto/AddressDTO.java [deleted file]
bundles/org.openhab.binding.myq/src/main/java/org/openhab/binding/myq/internal/dto/CountryDTO.java [deleted file]
bundles/org.openhab.binding.myq/src/main/java/org/openhab/binding/myq/internal/dto/DeviceDTO.java
bundles/org.openhab.binding.myq/src/main/java/org/openhab/binding/myq/internal/dto/DeviceStateDTO.java
bundles/org.openhab.binding.myq/src/main/java/org/openhab/binding/myq/internal/dto/TimeZoneDTO.java [deleted file]
bundles/org.openhab.binding.myq/src/main/java/org/openhab/binding/myq/internal/dto/UsersDTO.java [deleted file]
bundles/org.openhab.binding.myq/src/main/java/org/openhab/binding/myq/internal/handler/MyQAccountHandler.java
bundles/org.openhab.binding.myq/src/main/java/org/openhab/binding/myq/internal/handler/MyQGarageDoorHandler.java
bundles/org.openhab.binding.myq/src/main/java/org/openhab/binding/myq/internal/handler/MyQLampHandler.java

index 883d2988cf7369ec6b79f93ccc6401470f921c78..9a2464f4d0a0d126d3eba404aec79d07f26ae949 100644 (file)
@@ -14,11 +14,12 @@ package org.openhab.binding.myq.internal;
 
 import static org.openhab.binding.myq.internal.MyQBindingConstants.BINDING_ID;
 
+import java.util.List;
 import java.util.Set;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.myq.internal.dto.DevicesDTO;
+import org.openhab.binding.myq.internal.dto.DeviceDTO;
 import org.openhab.binding.myq.internal.handler.MyQAccountHandler;
 import org.openhab.core.config.discovery.AbstractDiscoveryService;
 import org.openhab.core.config.discovery.DiscoveryResult;
@@ -55,9 +56,9 @@ public class MyQDiscoveryService extends AbstractDiscoveryService implements Dis
     public void startScan() {
         MyQAccountHandler accountHandler = this.accountHandler;
         if (accountHandler != null) {
-            DevicesDTO devices = accountHandler.devicesCache();
+            List<DeviceDTO> devices = accountHandler.devicesCache();
             if (devices != null) {
-                devices.items.forEach(device -> {
+                devices.forEach(device -> {
                     ThingTypeUID thingTypeUID = new ThingTypeUID(BINDING_ID, device.deviceFamily);
                     if (SUPPORTED_DISCOVERY_THING_TYPES_UIDS.contains(thingTypeUID)) {
                         ThingUID thingUID = new ThingUID(thingTypeUID, accountHandler.getThing().getUID(),
@@ -73,6 +74,11 @@ public class MyQDiscoveryService extends AbstractDiscoveryService implements Dis
         }
     }
 
+    @Override
+    public void startBackgroundDiscovery() {
+        startScan();
+    }
+
     @Override
     public void setThingHandler(ThingHandler handler) {
         if (handler instanceof MyQAccountHandler) {
index 2957918320957402bf77cce66617b44be85eb3bd..e86853d2b4c76de56c4ead6603ff33d269fd92db 100644 (file)
@@ -18,21 +18,7 @@ package org.openhab.binding.myq.internal.dto;
  * @author Dan Cunningham - Initial contribution
  */
 public class AccountDTO {
-
-    public UsersDTO users;
-    public Boolean admin;
-    public AccountInfoDTO account;
-    public String analyticsId;
-    public String userId;
-    public String userName;
-    public String email;
-    public String firstName;
-    public String lastName;
-    public String cultureCode;
-    public AddressDTO address;
-    public TimeZoneDTO timeZone;
-    public Boolean mailingListOptIn;
-    public Boolean requestAccountLinkInfo;
-    public String phone;
-    public Boolean diagnosticDataOptIn;
+    public String id;
+    public String name;
+    public String createdBy;
 }
diff --git a/bundles/org.openhab.binding.myq/src/main/java/org/openhab/binding/myq/internal/dto/AccountInfoDTO.java b/bundles/org.openhab.binding.myq/src/main/java/org/openhab/binding/myq/internal/dto/AccountInfoDTO.java
deleted file mode 100644 (file)
index 193f464..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/**
- * Copyright (c) 2010-2021 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.myq.internal.dto;
-
-/**
- * The {@link AccountInfoDTO} entity from the MyQ API
- *
- * @author Dan Cunningham - Initial contribution
- */
-public class AccountInfoDTO {
-
-    public String href;
-    public String id;
-}
diff --git a/bundles/org.openhab.binding.myq/src/main/java/org/openhab/binding/myq/internal/dto/AccountsDTO.java b/bundles/org.openhab.binding.myq/src/main/java/org/openhab/binding/myq/internal/dto/AccountsDTO.java
new file mode 100644 (file)
index 0000000..88fcf9e
--- /dev/null
@@ -0,0 +1,24 @@
+/**
+ * Copyright (c) 2010-2021 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.myq.internal.dto;
+
+import java.util.List;
+
+/**
+ * The {@link AccountsDTO} entity from the MyQ API
+ *
+ * @author Dan Cunningham - Initial contribution
+ */
+public class AccountsDTO {
+    public List<AccountDTO> accounts;
+}
diff --git a/bundles/org.openhab.binding.myq/src/main/java/org/openhab/binding/myq/internal/dto/ActionDTO.java b/bundles/org.openhab.binding.myq/src/main/java/org/openhab/binding/myq/internal/dto/ActionDTO.java
deleted file mode 100644 (file)
index a38aa1e..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/**
- * Copyright (c) 2010-2021 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.myq.internal.dto;
-
-/**
- * The {@link ActionDTO} entity from the MyQ API
- *
- * @author Dan Cunningham - Initial contribution
- */
-public class ActionDTO {
-
-    public ActionDTO(String actionType) {
-        super();
-        this.actionType = actionType;
-    }
-
-    public String actionType;
-}
diff --git a/bundles/org.openhab.binding.myq/src/main/java/org/openhab/binding/myq/internal/dto/AddressDTO.java b/bundles/org.openhab.binding.myq/src/main/java/org/openhab/binding/myq/internal/dto/AddressDTO.java
deleted file mode 100644 (file)
index 1c4d858..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * Copyright (c) 2010-2021 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.myq.internal.dto;
-
-/**
- * The {@link AddressDTO} entity from the MyQ API
- *
- * @author Dan Cunningham - Initial contribution
- */
-public class AddressDTO {
-
-    public String addressLine1;
-    public String city;
-    public String postalCode;
-    public CountryDTO country;
-}
diff --git a/bundles/org.openhab.binding.myq/src/main/java/org/openhab/binding/myq/internal/dto/CountryDTO.java b/bundles/org.openhab.binding.myq/src/main/java/org/openhab/binding/myq/internal/dto/CountryDTO.java
deleted file mode 100644 (file)
index 594a1ee..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/**
- * Copyright (c) 2010-2021 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.myq.internal.dto;
-
-/**
- * The {@link CountryDTO} entity from the MyQ API
- *
- * @author Dan Cunningham - Initial contribution
- */
-public class CountryDTO {
-
-    public String code;
-    public Boolean isEEACountry;
-    public String href;
-}
index 426d691b2fcfb1c91235700cfcd594c31c537813..9cfe9a00407effc1247e807faed127bd3c3adca7 100644 (file)
@@ -25,6 +25,7 @@ public class DeviceDTO {
     public String deviceType;
     public String name;
     public String createdDate;
+    public String accountId;
     public DeviceStateDTO state;
     public String parentDevice;
     public String parentDeviceId;
index 169119b8c61160e492b376d61e6b5c5728845f46..331330c361df98c53eacb87bc44fc4bbcdebda81 100644 (file)
@@ -12,8 +12,6 @@
  */
 package org.openhab.binding.myq.internal.dto;
 
-import java.util.List;
-
 /**
  * The {@link DeviceStateDTO} entity from the MyQ API
  *
@@ -23,34 +21,16 @@ public class DeviceStateDTO {
 
     public Boolean gdoLockConnected;
     public Boolean attachedWorkLightErrorPresent;
-    public String doorState;
+    public String learnStatus;
+    public Boolean hasCamera;
     public String lampState;
-    public String open;
-    public String close;
+    public String batteryBackupState;
+    public String doorState;
     public String lastUpdate;
-    public String passthroughInterval;
-    public String doorAjarInterval;
-    public String invalidCredentialWindow;
-    public String invalidShutoutPeriod;
     public Boolean isUnattendedOpenAllowed;
     public Boolean isUnattendedCloseAllowed;
-    public String auxRelayDelay;
-    public Boolean useAuxRelay;
-    public String auxRelayBehavior;
-    public Boolean rexFiresDoor;
-    public Boolean commandChannelReportStatus;
-    public Boolean controlFromBrowser;
-    public Boolean reportForced;
-    public Boolean reportAjar;
-    public Integer maxInvalidAttempts;
+    public Integer serviceCycleCount;
+    public Integer absoluteCycleCount;
     public Boolean online;
     public String lastStatus;
-    public String firmwareVersion;
-    public Boolean homekitCapable;
-    public Boolean homekitEnabled;
-    public String learn;
-    public Boolean learnMode;
-    public String updatedDate;
-    public List<String> physicalDevices = null;
-    public Boolean pendingBootloadAbandoned;
 }
diff --git a/bundles/org.openhab.binding.myq/src/main/java/org/openhab/binding/myq/internal/dto/TimeZoneDTO.java b/bundles/org.openhab.binding.myq/src/main/java/org/openhab/binding/myq/internal/dto/TimeZoneDTO.java
deleted file mode 100644 (file)
index e324225..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/**
- * Copyright (c) 2010-2021 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.myq.internal.dto;
-
-/**
- * The {@link TimeZoneDTO} entity from the MyQ API
- *
- * @author Dan Cunningham - Initial contribution
- */
-public class TimeZoneDTO {
-
-    public String id;
-    public String name;
-}
diff --git a/bundles/org.openhab.binding.myq/src/main/java/org/openhab/binding/myq/internal/dto/UsersDTO.java b/bundles/org.openhab.binding.myq/src/main/java/org/openhab/binding/myq/internal/dto/UsersDTO.java
deleted file mode 100644 (file)
index c988dba..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/**
- * Copyright (c) 2010-2021 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.myq.internal.dto;
-
-/**
- * The {@link UsersDTO} entity from the MyQ API
- *
- * @author Dan Cunningham - Initial contribution
- */
-public class UsersDTO {
-
-    public String href;
-}
index a26760a616e2b4d2fa146892763997fd8e29584d..c769bcae1a6733840542141f10ad85e33fc303f4 100644 (file)
@@ -23,10 +23,12 @@ import java.net.URISyntaxException;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.security.SecureRandom;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Base64;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.List;
 import java.util.Map;
 import java.util.Random;
 import java.util.concurrent.CompletableFuture;
@@ -47,7 +49,6 @@ import org.eclipse.jetty.client.api.Response;
 import org.eclipse.jetty.client.api.Result;
 import org.eclipse.jetty.client.util.BufferingResponseListener;
 import org.eclipse.jetty.client.util.FormContentProvider;
-import org.eclipse.jetty.client.util.StringContentProvider;
 import org.eclipse.jetty.http.HttpMethod;
 import org.eclipse.jetty.http.HttpStatus;
 import org.eclipse.jetty.util.Fields;
@@ -57,7 +58,8 @@ import org.jsoup.nodes.Element;
 import org.openhab.binding.myq.internal.MyQDiscoveryService;
 import org.openhab.binding.myq.internal.config.MyQAccountConfiguration;
 import org.openhab.binding.myq.internal.dto.AccountDTO;
-import org.openhab.binding.myq.internal.dto.ActionDTO;
+import org.openhab.binding.myq.internal.dto.AccountsDTO;
+import org.openhab.binding.myq.internal.dto.DeviceDTO;
 import org.openhab.binding.myq.internal.dto.DevicesDTO;
 import org.openhab.core.auth.client.oauth2.AccessTokenRefreshListener;
 import org.openhab.core.auth.client.oauth2.AccessTokenResponse;
@@ -106,20 +108,23 @@ public class MyQAccountHandler extends BaseBridgeHandler implements AccessTokenR
     // this should never happen, but lets be safe and give up after so many redirects
     private static final int LOGIN_MAX_REDIRECTS = 30;
     /*
-     * MyQ device and account API endpoint
+     * MyQ device and account API endpoints
      */
-    private static final String BASE_URL = "https://api.myqdevice.com/api";
+    private static final String ACCOUNTS_URL = "https://accounts.myq-cloud.com/api/v6.0/accounts";
+    private static final String DEVICES_URL = "https://devices.myq-cloud.com/api/v5.2/Accounts/%s/Devices";
+    private static final String CMD_LAMP_URL = "https://account-devices-lamp.myq-cloud.com/api/v5.2/Accounts/%s/lamps/%s/%s";
+    private static final String CMD_DOOR_URL = "https://account-devices-gdo.myq-cloud.com/api/v5.2/Accounts/%s/door_openers/%s/%s";
+
     private static final Integer RAPID_REFRESH_SECONDS = 5;
     private final Logger logger = LoggerFactory.getLogger(MyQAccountHandler.class);
-    private final Gson gsonUpperCase = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)
-            .create();
     private final Gson gsonLowerCase = new GsonBuilder()
             .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
     private final OAuthFactory oAuthFactory;
     private @Nullable Future<?> normalPollFuture;
     private @Nullable Future<?> rapidPollFuture;
-    private @Nullable AccountDTO account;
-    private @Nullable DevicesDTO devicesCache;
+    private @Nullable AccountsDTO accounts;
+
+    private List<DeviceDTO> devicesCache = new ArrayList<DeviceDTO>();
     private @Nullable OAuthClientService oAuthService;
     private Integer normalRefreshSeconds = 60;
     private HttpClient httpClient;
@@ -155,6 +160,7 @@ public class MyQAccountHandler extends BaseBridgeHandler implements AccessTokenR
     @Override
     public void dispose() {
         stopPolls();
+        OAuthClientService oAuthService = this.oAuthService;
         if (oAuthService != null) {
             oAuthService.close();
         }
@@ -167,10 +173,10 @@ public class MyQAccountHandler extends BaseBridgeHandler implements AccessTokenR
 
     @Override
     public void childHandlerInitialized(ThingHandler childHandler, Thing childThing) {
-        DevicesDTO localDeviceCaches = devicesCache;
-        if (localDeviceCaches != null && childHandler instanceof MyQDeviceHandler) {
+        List<DeviceDTO> localDeviceCaches = devicesCache;
+        if (childHandler instanceof MyQDeviceHandler) {
             MyQDeviceHandler handler = (MyQDeviceHandler) childHandler;
-            localDeviceCaches.items.stream()
+            localDeviceCaches.stream()
                     .filter(d -> ((MyQDeviceHandler) childHandler).getSerialNumber().equalsIgnoreCase(d.serialNumber))
                     .findFirst().ifPresent(handler::handleDeviceUpdate);
         }
@@ -182,33 +188,42 @@ public class MyQAccountHandler extends BaseBridgeHandler implements AccessTokenR
     }
 
     /**
-     * Sends an action to the MyQ API
+     * Sends a door action to the MyQ API
+     *
+     * @param device
+     * @param action
+     */
+    public void sendDoorAction(DeviceDTO device, String action) {
+        sendAction(device, action, CMD_DOOR_URL);
+    }
+
+    /**
+     * Sends a lamp action to the MyQ API
      *
-     * @param serialNumber
+     * @param device
      * @param action
      */
-    public void sendAction(String serialNumber, String action) {
+    public void sendLampAction(DeviceDTO device, String action) {
+        sendAction(device, action, CMD_LAMP_URL);
+    }
+
+    private void sendAction(DeviceDTO device, String action, String urlFormat) {
         if (getThing().getStatus() != ThingStatus.ONLINE) {
             logger.debug("Account offline, ignoring action {}", action);
             return;
         }
 
-        AccountDTO localAccount = account;
-        if (localAccount != null) {
-            try {
-                ContentResponse response = sendRequest(
-                        String.format("%s/v5.1/Accounts/%s/Devices/%s/actions", BASE_URL, localAccount.account.id,
-                                serialNumber),
-                        HttpMethod.PUT, new StringContentProvider(gsonLowerCase.toJson(new ActionDTO(action))),
-                        "application/json");
-                if (HttpStatus.isSuccess(response.getStatus())) {
-                    restartPolls(true);
-                } else {
-                    logger.debug("Failed to send action {} : {}", action, response.getContentAsString());
-                }
-            } catch (InterruptedException | MyQCommunicationException | MyQAuthenticationException e) {
-                logger.debug("Could not send action", e);
+        try {
+            ContentResponse response = sendRequest(
+                    String.format(urlFormat, device.accountId, device.serialNumber, action), HttpMethod.PUT, null,
+                    null);
+            if (HttpStatus.isSuccess(response.getStatus())) {
+                restartPolls(true);
+            } else {
+                logger.debug("Failed to send action {} : {}", action, response.getContentAsString());
             }
+        } catch (InterruptedException | MyQCommunicationException | MyQAuthenticationException e) {
+            logger.debug("Could not send action", e);
         }
     }
 
@@ -217,7 +232,7 @@ public class MyQAccountHandler extends BaseBridgeHandler implements AccessTokenR
      *
      * @return cached MyQ devices
      */
-    public @Nullable DevicesDTO devicesCache() {
+    public @Nullable List<DeviceDTO> devicesCache() {
         return devicesCache;
     }
 
@@ -266,8 +281,8 @@ public class MyQAccountHandler extends BaseBridgeHandler implements AccessTokenR
 
     private synchronized void fetchData() {
         try {
-            if (account == null) {
-                getAccount();
+            if (accounts == null) {
+                getAccounts();
             }
             getDevices();
         } catch (MyQCommunicationException e) {
@@ -338,33 +353,37 @@ public class MyQAccountHandler extends BaseBridgeHandler implements AccessTokenR
         }
     }
 
-    private void getAccount() throws InterruptedException, MyQCommunicationException, MyQAuthenticationException {
-        ContentResponse response = sendRequest(BASE_URL + "/v5/My?expand=account", HttpMethod.GET, null, null);
-        account = parseResultAndUpdateStatus(response, gsonUpperCase, AccountDTO.class);
+    private void getAccounts() throws InterruptedException, MyQCommunicationException, MyQAuthenticationException {
+        ContentResponse response = sendRequest(ACCOUNTS_URL, HttpMethod.GET, null, null);
+        accounts = parseResultAndUpdateStatus(response, gsonLowerCase, AccountsDTO.class);
     }
 
     private void getDevices() throws InterruptedException, MyQCommunicationException, MyQAuthenticationException {
-        AccountDTO localAccount = account;
-        if (localAccount == null) {
+        AccountsDTO localAccounts = accounts;
+        if (localAccounts == null) {
             return;
         }
-        ContentResponse response = sendRequest(
-                String.format("%s/v5.1/Accounts/%s/Devices", BASE_URL, localAccount.account.id), HttpMethod.GET, null,
-                null);
-        DevicesDTO devices = parseResultAndUpdateStatus(response, gsonLowerCase, DevicesDTO.class);
-        devicesCache = devices;
-        devices.items.forEach(device -> {
-            ThingTypeUID thingTypeUID = new ThingTypeUID(BINDING_ID, device.deviceFamily);
-            if (SUPPORTED_DISCOVERY_THING_TYPES_UIDS.contains(thingTypeUID)) {
-                for (Thing thing : getThing().getThings()) {
-                    ThingHandler handler = thing.getHandler();
-                    if (handler != null
-                            && ((MyQDeviceHandler) handler).getSerialNumber().equalsIgnoreCase(device.serialNumber)) {
-                        ((MyQDeviceHandler) handler).handleDeviceUpdate(device);
+
+        List<DeviceDTO> currentDevices = new ArrayList<DeviceDTO>();
+
+        for (AccountDTO account : localAccounts.accounts) {
+            ContentResponse response = sendRequest(String.format(DEVICES_URL, account.id), HttpMethod.GET, null, null);
+            DevicesDTO devices = parseResultAndUpdateStatus(response, gsonLowerCase, DevicesDTO.class);
+            currentDevices.addAll(devices.items);
+            devices.items.forEach(device -> {
+                ThingTypeUID thingTypeUID = new ThingTypeUID(BINDING_ID, device.deviceFamily);
+                if (SUPPORTED_DISCOVERY_THING_TYPES_UIDS.contains(thingTypeUID)) {
+                    for (Thing thing : getThing().getThings()) {
+                        ThingHandler handler = thing.getHandler();
+                        if (handler != null && ((MyQDeviceHandler) handler).getSerialNumber()
+                                .equalsIgnoreCase(device.serialNumber)) {
+                            ((MyQDeviceHandler) handler).handleDeviceUpdate(device);
+                        }
                     }
                 }
-            }
-        });
+            });
+        }
+        devicesCache = currentDevices;
     }
 
     private synchronized ContentResponse sendRequest(String url, HttpMethod method, @Nullable ContentProvider content,
index a2422f3d0feebc2ea0bb2dfd186570f3f42b8dad..0d5ff03cc653c60dee9f76c3f1b67125ecca7e83 100644 (file)
@@ -40,7 +40,7 @@ import org.openhab.core.types.UnDefType;
  */
 @NonNullByDefault
 public class MyQGarageDoorHandler extends BaseThingHandler implements MyQDeviceHandler {
-    private @Nullable DeviceDTO deviceState;
+    private @Nullable DeviceDTO device;
     private String serialNumber;
 
     public MyQGarageDoorHandler(Thing thing) {
@@ -60,8 +60,8 @@ public class MyQGarageDoorHandler extends BaseThingHandler implements MyQDeviceH
             return;
         }
         Bridge bridge = getBridge();
-        final DeviceDTO localState = deviceState;
-        if (bridge != null && localState != null) {
+        final DeviceDTO localDevice = device;
+        if (bridge != null && localDevice != null) {
             BridgeHandler handler = bridge.getHandler();
             if (handler != null) {
                 String cmd = null;
@@ -78,7 +78,7 @@ public class MyQGarageDoorHandler extends BaseThingHandler implements MyQDeviceH
                     cmd = command.toString();
                 }
                 if (cmd != null) {
-                    ((MyQAccountHandler) handler).sendAction(localState.serialNumber, cmd);
+                    ((MyQAccountHandler) handler).sendDoorAction(localDevice, cmd);
                 }
             }
         }
@@ -90,9 +90,9 @@ public class MyQGarageDoorHandler extends BaseThingHandler implements MyQDeviceH
     }
 
     protected void updateState() {
-        final DeviceDTO localState = deviceState;
-        if (localState != null) {
-            String doorState = localState.state.doorState;
+        final DeviceDTO localDevice = device;
+        if (localDevice != null) {
+            String doorState = localDevice.state.doorState;
             updateState("status", new StringType(doorState));
             switch (doorState) {
                 case "open":
@@ -112,8 +112,8 @@ public class MyQGarageDoorHandler extends BaseThingHandler implements MyQDeviceH
                     updateState("rollershutter", UnDefType.UNDEF);
                     break;
             }
-            updateState("closeerror", localState.state.isUnattendedCloseAllowed ? OnOffType.OFF : OnOffType.ON);
-            updateState("openerror", localState.state.isUnattendedOpenAllowed ? OnOffType.OFF : OnOffType.ON);
+            updateState("closeerror", localDevice.state.isUnattendedCloseAllowed ? OnOffType.OFF : OnOffType.ON);
+            updateState("openerror", localDevice.state.isUnattendedOpenAllowed ? OnOffType.OFF : OnOffType.ON);
         }
     }
 
@@ -122,7 +122,7 @@ public class MyQGarageDoorHandler extends BaseThingHandler implements MyQDeviceH
         if (!MyQBindingConstants.THING_TYPE_GARAGEDOOR.getId().equals(device.deviceFamily)) {
             return;
         }
-        deviceState = device;
+        this.device = device;
         if (device.state.online) {
             updateStatus(ThingStatus.ONLINE);
             updateState();
index e7988bae00ee4edc5bb4d7dcb01f7f437aee2419..80c537eee5b4bc173ffc81e9c345ebaa4c541d9c 100644 (file)
@@ -36,7 +36,7 @@ import org.openhab.core.types.RefreshType;
  */
 @NonNullByDefault
 public class MyQLampHandler extends BaseThingHandler implements MyQDeviceHandler {
-    private @Nullable DeviceDTO deviceState;
+    private @Nullable DeviceDTO device;
     private String serialNumber;
 
     public MyQLampHandler(Thing thing) {
@@ -58,11 +58,11 @@ public class MyQLampHandler extends BaseThingHandler implements MyQDeviceHandler
 
         if (command instanceof OnOffType) {
             Bridge bridge = getBridge();
-            final DeviceDTO localState = deviceState;
-            if (bridge != null && localState != null) {
+            final DeviceDTO localDevice = device;
+            if (bridge != null && localDevice != null) {
                 BridgeHandler handler = bridge.getHandler();
                 if (handler != null) {
-                    ((MyQAccountHandler) handler).sendAction(localState.serialNumber,
+                    ((MyQAccountHandler) handler).sendLampAction(localDevice,
                             command == OnOffType.ON ? "turnon" : "turnoff");
                 }
             }
@@ -75,9 +75,9 @@ public class MyQLampHandler extends BaseThingHandler implements MyQDeviceHandler
     }
 
     protected void updateState() {
-        final DeviceDTO localState = deviceState;
-        if (localState != null) {
-            String lampState = localState.state.lampState;
+        final DeviceDTO localDevice = device;
+        if (localDevice != null) {
+            String lampState = localDevice.state.lampState;
             updateState("switch", "on".equals(lampState) ? OnOffType.ON : OnOffType.OFF);
         }
     }
@@ -87,7 +87,7 @@ public class MyQLampHandler extends BaseThingHandler implements MyQDeviceHandler
         if (!MyQBindingConstants.THING_TYPE_LAMP.getId().equals(device.deviceFamily)) {
             return;
         }
-        deviceState = device;
+        this.device = device;
         if (device.state.online) {
             updateStatus(ThingStatus.ONLINE);
             updateState();