[myq] Fixes breaking API changes to the MyQ binding (#11601)
Signed-off-by: Dan Cunningham <dan@digitaldan.com>
This commit is contained in:
parent
163a34fca4
commit
d0837ae8a2
@ -14,11 +14,12 @@ package org.openhab.binding.myq.internal;
|
|||||||
|
|
||||||
import static org.openhab.binding.myq.internal.MyQBindingConstants.BINDING_ID;
|
import static org.openhab.binding.myq.internal.MyQBindingConstants.BINDING_ID;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
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.binding.myq.internal.handler.MyQAccountHandler;
|
||||||
import org.openhab.core.config.discovery.AbstractDiscoveryService;
|
import org.openhab.core.config.discovery.AbstractDiscoveryService;
|
||||||
import org.openhab.core.config.discovery.DiscoveryResult;
|
import org.openhab.core.config.discovery.DiscoveryResult;
|
||||||
@ -55,9 +56,9 @@ public class MyQDiscoveryService extends AbstractDiscoveryService implements Dis
|
|||||||
public void startScan() {
|
public void startScan() {
|
||||||
MyQAccountHandler accountHandler = this.accountHandler;
|
MyQAccountHandler accountHandler = this.accountHandler;
|
||||||
if (accountHandler != null) {
|
if (accountHandler != null) {
|
||||||
DevicesDTO devices = accountHandler.devicesCache();
|
List<DeviceDTO> devices = accountHandler.devicesCache();
|
||||||
if (devices != null) {
|
if (devices != null) {
|
||||||
devices.items.forEach(device -> {
|
devices.forEach(device -> {
|
||||||
ThingTypeUID thingTypeUID = new ThingTypeUID(BINDING_ID, device.deviceFamily);
|
ThingTypeUID thingTypeUID = new ThingTypeUID(BINDING_ID, device.deviceFamily);
|
||||||
if (SUPPORTED_DISCOVERY_THING_TYPES_UIDS.contains(thingTypeUID)) {
|
if (SUPPORTED_DISCOVERY_THING_TYPES_UIDS.contains(thingTypeUID)) {
|
||||||
ThingUID thingUID = new ThingUID(thingTypeUID, accountHandler.getThing().getUID(),
|
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
|
@Override
|
||||||
public void setThingHandler(ThingHandler handler) {
|
public void setThingHandler(ThingHandler handler) {
|
||||||
if (handler instanceof MyQAccountHandler) {
|
if (handler instanceof MyQAccountHandler) {
|
||||||
|
|||||||
@ -18,21 +18,7 @@ package org.openhab.binding.myq.internal.dto;
|
|||||||
* @author Dan Cunningham - Initial contribution
|
* @author Dan Cunningham - Initial contribution
|
||||||
*/
|
*/
|
||||||
public class AccountDTO {
|
public class AccountDTO {
|
||||||
|
public String id;
|
||||||
public UsersDTO users;
|
public String name;
|
||||||
public Boolean admin;
|
public String createdBy;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,13 +12,13 @@
|
|||||||
*/
|
*/
|
||||||
package org.openhab.binding.myq.internal.dto;
|
package org.openhab.binding.myq.internal.dto;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link AccountInfoDTO} entity from the MyQ API
|
* The {@link AccountsDTO} entity from the MyQ API
|
||||||
*
|
*
|
||||||
* @author Dan Cunningham - Initial contribution
|
* @author Dan Cunningham - Initial contribution
|
||||||
*/
|
*/
|
||||||
public class AccountInfoDTO {
|
public class AccountsDTO {
|
||||||
|
public List<AccountDTO> accounts;
|
||||||
public String href;
|
|
||||||
public String id;
|
|
||||||
}
|
}
|
||||||
@ -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;
|
|
||||||
}
|
|
||||||
@ -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;
|
|
||||||
}
|
|
||||||
@ -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;
|
|
||||||
}
|
|
||||||
@ -25,6 +25,7 @@ public class DeviceDTO {
|
|||||||
public String deviceType;
|
public String deviceType;
|
||||||
public String name;
|
public String name;
|
||||||
public String createdDate;
|
public String createdDate;
|
||||||
|
public String accountId;
|
||||||
public DeviceStateDTO state;
|
public DeviceStateDTO state;
|
||||||
public String parentDevice;
|
public String parentDevice;
|
||||||
public String parentDeviceId;
|
public String parentDeviceId;
|
||||||
|
|||||||
@ -12,8 +12,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.openhab.binding.myq.internal.dto;
|
package org.openhab.binding.myq.internal.dto;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link DeviceStateDTO} entity from the MyQ API
|
* The {@link DeviceStateDTO} entity from the MyQ API
|
||||||
*
|
*
|
||||||
@ -23,34 +21,16 @@ public class DeviceStateDTO {
|
|||||||
|
|
||||||
public Boolean gdoLockConnected;
|
public Boolean gdoLockConnected;
|
||||||
public Boolean attachedWorkLightErrorPresent;
|
public Boolean attachedWorkLightErrorPresent;
|
||||||
public String doorState;
|
public String learnStatus;
|
||||||
|
public Boolean hasCamera;
|
||||||
public String lampState;
|
public String lampState;
|
||||||
public String open;
|
public String batteryBackupState;
|
||||||
public String close;
|
public String doorState;
|
||||||
public String lastUpdate;
|
public String lastUpdate;
|
||||||
public String passthroughInterval;
|
|
||||||
public String doorAjarInterval;
|
|
||||||
public String invalidCredentialWindow;
|
|
||||||
public String invalidShutoutPeriod;
|
|
||||||
public Boolean isUnattendedOpenAllowed;
|
public Boolean isUnattendedOpenAllowed;
|
||||||
public Boolean isUnattendedCloseAllowed;
|
public Boolean isUnattendedCloseAllowed;
|
||||||
public String auxRelayDelay;
|
public Integer serviceCycleCount;
|
||||||
public Boolean useAuxRelay;
|
public Integer absoluteCycleCount;
|
||||||
public String auxRelayBehavior;
|
|
||||||
public Boolean rexFiresDoor;
|
|
||||||
public Boolean commandChannelReportStatus;
|
|
||||||
public Boolean controlFromBrowser;
|
|
||||||
public Boolean reportForced;
|
|
||||||
public Boolean reportAjar;
|
|
||||||
public Integer maxInvalidAttempts;
|
|
||||||
public Boolean online;
|
public Boolean online;
|
||||||
public String lastStatus;
|
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;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
|
||||||
}
|
|
||||||
@ -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;
|
|
||||||
}
|
|
||||||
@ -23,10 +23,12 @@ import java.net.URISyntaxException;
|
|||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.concurrent.CompletableFuture;
|
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.api.Result;
|
||||||
import org.eclipse.jetty.client.util.BufferingResponseListener;
|
import org.eclipse.jetty.client.util.BufferingResponseListener;
|
||||||
import org.eclipse.jetty.client.util.FormContentProvider;
|
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.HttpMethod;
|
||||||
import org.eclipse.jetty.http.HttpStatus;
|
import org.eclipse.jetty.http.HttpStatus;
|
||||||
import org.eclipse.jetty.util.Fields;
|
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.MyQDiscoveryService;
|
||||||
import org.openhab.binding.myq.internal.config.MyQAccountConfiguration;
|
import org.openhab.binding.myq.internal.config.MyQAccountConfiguration;
|
||||||
import org.openhab.binding.myq.internal.dto.AccountDTO;
|
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.binding.myq.internal.dto.DevicesDTO;
|
||||||
import org.openhab.core.auth.client.oauth2.AccessTokenRefreshListener;
|
import org.openhab.core.auth.client.oauth2.AccessTokenRefreshListener;
|
||||||
import org.openhab.core.auth.client.oauth2.AccessTokenResponse;
|
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
|
// this should never happen, but lets be safe and give up after so many redirects
|
||||||
private static final int LOGIN_MAX_REDIRECTS = 30;
|
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 static final Integer RAPID_REFRESH_SECONDS = 5;
|
||||||
private final Logger logger = LoggerFactory.getLogger(MyQAccountHandler.class);
|
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()
|
private final Gson gsonLowerCase = new GsonBuilder()
|
||||||
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
|
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
|
||||||
private final OAuthFactory oAuthFactory;
|
private final OAuthFactory oAuthFactory;
|
||||||
private @Nullable Future<?> normalPollFuture;
|
private @Nullable Future<?> normalPollFuture;
|
||||||
private @Nullable Future<?> rapidPollFuture;
|
private @Nullable Future<?> rapidPollFuture;
|
||||||
private @Nullable AccountDTO account;
|
private @Nullable AccountsDTO accounts;
|
||||||
private @Nullable DevicesDTO devicesCache;
|
|
||||||
|
private List<DeviceDTO> devicesCache = new ArrayList<DeviceDTO>();
|
||||||
private @Nullable OAuthClientService oAuthService;
|
private @Nullable OAuthClientService oAuthService;
|
||||||
private Integer normalRefreshSeconds = 60;
|
private Integer normalRefreshSeconds = 60;
|
||||||
private HttpClient httpClient;
|
private HttpClient httpClient;
|
||||||
@ -155,6 +160,7 @@ public class MyQAccountHandler extends BaseBridgeHandler implements AccessTokenR
|
|||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
stopPolls();
|
stopPolls();
|
||||||
|
OAuthClientService oAuthService = this.oAuthService;
|
||||||
if (oAuthService != null) {
|
if (oAuthService != null) {
|
||||||
oAuthService.close();
|
oAuthService.close();
|
||||||
}
|
}
|
||||||
@ -167,10 +173,10 @@ public class MyQAccountHandler extends BaseBridgeHandler implements AccessTokenR
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void childHandlerInitialized(ThingHandler childHandler, Thing childThing) {
|
public void childHandlerInitialized(ThingHandler childHandler, Thing childThing) {
|
||||||
DevicesDTO localDeviceCaches = devicesCache;
|
List<DeviceDTO> localDeviceCaches = devicesCache;
|
||||||
if (localDeviceCaches != null && childHandler instanceof MyQDeviceHandler) {
|
if (childHandler instanceof MyQDeviceHandler) {
|
||||||
MyQDeviceHandler handler = (MyQDeviceHandler) childHandler;
|
MyQDeviceHandler handler = (MyQDeviceHandler) childHandler;
|
||||||
localDeviceCaches.items.stream()
|
localDeviceCaches.stream()
|
||||||
.filter(d -> ((MyQDeviceHandler) childHandler).getSerialNumber().equalsIgnoreCase(d.serialNumber))
|
.filter(d -> ((MyQDeviceHandler) childHandler).getSerialNumber().equalsIgnoreCase(d.serialNumber))
|
||||||
.findFirst().ifPresent(handler::handleDeviceUpdate);
|
.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 serialNumber
|
* @param device
|
||||||
* @param action
|
* @param action
|
||||||
*/
|
*/
|
||||||
public void sendAction(String serialNumber, String action) {
|
public void sendDoorAction(DeviceDTO device, String action) {
|
||||||
|
sendAction(device, action, CMD_DOOR_URL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a lamp action to the MyQ API
|
||||||
|
*
|
||||||
|
* @param device
|
||||||
|
* @param 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) {
|
if (getThing().getStatus() != ThingStatus.ONLINE) {
|
||||||
logger.debug("Account offline, ignoring action {}", action);
|
logger.debug("Account offline, ignoring action {}", action);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AccountDTO localAccount = account;
|
try {
|
||||||
if (localAccount != null) {
|
ContentResponse response = sendRequest(
|
||||||
try {
|
String.format(urlFormat, device.accountId, device.serialNumber, action), HttpMethod.PUT, null,
|
||||||
ContentResponse response = sendRequest(
|
null);
|
||||||
String.format("%s/v5.1/Accounts/%s/Devices/%s/actions", BASE_URL, localAccount.account.id,
|
if (HttpStatus.isSuccess(response.getStatus())) {
|
||||||
serialNumber),
|
restartPolls(true);
|
||||||
HttpMethod.PUT, new StringContentProvider(gsonLowerCase.toJson(new ActionDTO(action))),
|
} else {
|
||||||
"application/json");
|
logger.debug("Failed to send action {} : {}", action, response.getContentAsString());
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
} 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
|
* @return cached MyQ devices
|
||||||
*/
|
*/
|
||||||
public @Nullable DevicesDTO devicesCache() {
|
public @Nullable List<DeviceDTO> devicesCache() {
|
||||||
return devicesCache;
|
return devicesCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,8 +281,8 @@ public class MyQAccountHandler extends BaseBridgeHandler implements AccessTokenR
|
|||||||
|
|
||||||
private synchronized void fetchData() {
|
private synchronized void fetchData() {
|
||||||
try {
|
try {
|
||||||
if (account == null) {
|
if (accounts == null) {
|
||||||
getAccount();
|
getAccounts();
|
||||||
}
|
}
|
||||||
getDevices();
|
getDevices();
|
||||||
} catch (MyQCommunicationException e) {
|
} catch (MyQCommunicationException e) {
|
||||||
@ -338,33 +353,37 @@ public class MyQAccountHandler extends BaseBridgeHandler implements AccessTokenR
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getAccount() throws InterruptedException, MyQCommunicationException, MyQAuthenticationException {
|
private void getAccounts() throws InterruptedException, MyQCommunicationException, MyQAuthenticationException {
|
||||||
ContentResponse response = sendRequest(BASE_URL + "/v5/My?expand=account", HttpMethod.GET, null, null);
|
ContentResponse response = sendRequest(ACCOUNTS_URL, HttpMethod.GET, null, null);
|
||||||
account = parseResultAndUpdateStatus(response, gsonUpperCase, AccountDTO.class);
|
accounts = parseResultAndUpdateStatus(response, gsonLowerCase, AccountsDTO.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getDevices() throws InterruptedException, MyQCommunicationException, MyQAuthenticationException {
|
private void getDevices() throws InterruptedException, MyQCommunicationException, MyQAuthenticationException {
|
||||||
AccountDTO localAccount = account;
|
AccountsDTO localAccounts = accounts;
|
||||||
if (localAccount == null) {
|
if (localAccounts == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ContentResponse response = sendRequest(
|
|
||||||
String.format("%s/v5.1/Accounts/%s/Devices", BASE_URL, localAccount.account.id), HttpMethod.GET, null,
|
List<DeviceDTO> currentDevices = new ArrayList<DeviceDTO>();
|
||||||
null);
|
|
||||||
DevicesDTO devices = parseResultAndUpdateStatus(response, gsonLowerCase, DevicesDTO.class);
|
for (AccountDTO account : localAccounts.accounts) {
|
||||||
devicesCache = devices;
|
ContentResponse response = sendRequest(String.format(DEVICES_URL, account.id), HttpMethod.GET, null, null);
|
||||||
devices.items.forEach(device -> {
|
DevicesDTO devices = parseResultAndUpdateStatus(response, gsonLowerCase, DevicesDTO.class);
|
||||||
ThingTypeUID thingTypeUID = new ThingTypeUID(BINDING_ID, device.deviceFamily);
|
currentDevices.addAll(devices.items);
|
||||||
if (SUPPORTED_DISCOVERY_THING_TYPES_UIDS.contains(thingTypeUID)) {
|
devices.items.forEach(device -> {
|
||||||
for (Thing thing : getThing().getThings()) {
|
ThingTypeUID thingTypeUID = new ThingTypeUID(BINDING_ID, device.deviceFamily);
|
||||||
ThingHandler handler = thing.getHandler();
|
if (SUPPORTED_DISCOVERY_THING_TYPES_UIDS.contains(thingTypeUID)) {
|
||||||
if (handler != null
|
for (Thing thing : getThing().getThings()) {
|
||||||
&& ((MyQDeviceHandler) handler).getSerialNumber().equalsIgnoreCase(device.serialNumber)) {
|
ThingHandler handler = thing.getHandler();
|
||||||
((MyQDeviceHandler) handler).handleDeviceUpdate(device);
|
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,
|
private synchronized ContentResponse sendRequest(String url, HttpMethod method, @Nullable ContentProvider content,
|
||||||
|
|||||||
@ -40,7 +40,7 @@ import org.openhab.core.types.UnDefType;
|
|||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
public class MyQGarageDoorHandler extends BaseThingHandler implements MyQDeviceHandler {
|
public class MyQGarageDoorHandler extends BaseThingHandler implements MyQDeviceHandler {
|
||||||
private @Nullable DeviceDTO deviceState;
|
private @Nullable DeviceDTO device;
|
||||||
private String serialNumber;
|
private String serialNumber;
|
||||||
|
|
||||||
public MyQGarageDoorHandler(Thing thing) {
|
public MyQGarageDoorHandler(Thing thing) {
|
||||||
@ -60,8 +60,8 @@ public class MyQGarageDoorHandler extends BaseThingHandler implements MyQDeviceH
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Bridge bridge = getBridge();
|
Bridge bridge = getBridge();
|
||||||
final DeviceDTO localState = deviceState;
|
final DeviceDTO localDevice = device;
|
||||||
if (bridge != null && localState != null) {
|
if (bridge != null && localDevice != null) {
|
||||||
BridgeHandler handler = bridge.getHandler();
|
BridgeHandler handler = bridge.getHandler();
|
||||||
if (handler != null) {
|
if (handler != null) {
|
||||||
String cmd = null;
|
String cmd = null;
|
||||||
@ -78,7 +78,7 @@ public class MyQGarageDoorHandler extends BaseThingHandler implements MyQDeviceH
|
|||||||
cmd = command.toString();
|
cmd = command.toString();
|
||||||
}
|
}
|
||||||
if (cmd != null) {
|
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() {
|
protected void updateState() {
|
||||||
final DeviceDTO localState = deviceState;
|
final DeviceDTO localDevice = device;
|
||||||
if (localState != null) {
|
if (localDevice != null) {
|
||||||
String doorState = localState.state.doorState;
|
String doorState = localDevice.state.doorState;
|
||||||
updateState("status", new StringType(doorState));
|
updateState("status", new StringType(doorState));
|
||||||
switch (doorState) {
|
switch (doorState) {
|
||||||
case "open":
|
case "open":
|
||||||
@ -112,8 +112,8 @@ public class MyQGarageDoorHandler extends BaseThingHandler implements MyQDeviceH
|
|||||||
updateState("rollershutter", UnDefType.UNDEF);
|
updateState("rollershutter", UnDefType.UNDEF);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
updateState("closeerror", localState.state.isUnattendedCloseAllowed ? OnOffType.OFF : OnOffType.ON);
|
updateState("closeerror", localDevice.state.isUnattendedCloseAllowed ? OnOffType.OFF : OnOffType.ON);
|
||||||
updateState("openerror", localState.state.isUnattendedOpenAllowed ? 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)) {
|
if (!MyQBindingConstants.THING_TYPE_GARAGEDOOR.getId().equals(device.deviceFamily)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
deviceState = device;
|
this.device = device;
|
||||||
if (device.state.online) {
|
if (device.state.online) {
|
||||||
updateStatus(ThingStatus.ONLINE);
|
updateStatus(ThingStatus.ONLINE);
|
||||||
updateState();
|
updateState();
|
||||||
|
|||||||
@ -36,7 +36,7 @@ import org.openhab.core.types.RefreshType;
|
|||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
public class MyQLampHandler extends BaseThingHandler implements MyQDeviceHandler {
|
public class MyQLampHandler extends BaseThingHandler implements MyQDeviceHandler {
|
||||||
private @Nullable DeviceDTO deviceState;
|
private @Nullable DeviceDTO device;
|
||||||
private String serialNumber;
|
private String serialNumber;
|
||||||
|
|
||||||
public MyQLampHandler(Thing thing) {
|
public MyQLampHandler(Thing thing) {
|
||||||
@ -58,11 +58,11 @@ public class MyQLampHandler extends BaseThingHandler implements MyQDeviceHandler
|
|||||||
|
|
||||||
if (command instanceof OnOffType) {
|
if (command instanceof OnOffType) {
|
||||||
Bridge bridge = getBridge();
|
Bridge bridge = getBridge();
|
||||||
final DeviceDTO localState = deviceState;
|
final DeviceDTO localDevice = device;
|
||||||
if (bridge != null && localState != null) {
|
if (bridge != null && localDevice != null) {
|
||||||
BridgeHandler handler = bridge.getHandler();
|
BridgeHandler handler = bridge.getHandler();
|
||||||
if (handler != null) {
|
if (handler != null) {
|
||||||
((MyQAccountHandler) handler).sendAction(localState.serialNumber,
|
((MyQAccountHandler) handler).sendLampAction(localDevice,
|
||||||
command == OnOffType.ON ? "turnon" : "turnoff");
|
command == OnOffType.ON ? "turnon" : "turnoff");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,9 +75,9 @@ public class MyQLampHandler extends BaseThingHandler implements MyQDeviceHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void updateState() {
|
protected void updateState() {
|
||||||
final DeviceDTO localState = deviceState;
|
final DeviceDTO localDevice = device;
|
||||||
if (localState != null) {
|
if (localDevice != null) {
|
||||||
String lampState = localState.state.lampState;
|
String lampState = localDevice.state.lampState;
|
||||||
updateState("switch", "on".equals(lampState) ? OnOffType.ON : OnOffType.OFF);
|
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)) {
|
if (!MyQBindingConstants.THING_TYPE_LAMP.getId().equals(device.deviceFamily)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
deviceState = device;
|
this.device = device;
|
||||||
if (device.state.online) {
|
if (device.state.online) {
|
||||||
updateStatus(ThingStatus.ONLINE);
|
updateStatus(ThingStatus.ONLINE);
|
||||||
updateState();
|
updateState();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user