From 7396a394f127888278df08c9fc0cfdd3d83472ba Mon Sep 17 00:00:00 2001 From: Arne Seime Date: Tue, 26 Nov 2024 22:08:26 +0100 Subject: [PATCH] Added some random delays to avoid cloudfront rate limiting --- .../panasoniccomfortcloud/internal/ApiBridge.java | 11 ++++++----- .../PanasonicComfortCloudAccountHandler.java | 13 +++++++++++-- .../PanasonicComfortCloudAirconditionHandler.java | 5 ++++- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/main/java/no/seime/openhab/binding/panasoniccomfortcloud/internal/ApiBridge.java b/src/main/java/no/seime/openhab/binding/panasoniccomfortcloud/internal/ApiBridge.java index 8b0f39a..f481176 100644 --- a/src/main/java/no/seime/openhab/binding/panasoniccomfortcloud/internal/ApiBridge.java +++ b/src/main/java/no/seime/openhab/binding/panasoniccomfortcloud/internal/ApiBridge.java @@ -89,7 +89,7 @@ public ApiBridge(Storage storage) { this.storage = storage; HttpLoggingInterceptor logging = new HttpLoggingInterceptor(message -> logger.debug(message)); logging.setLevel(HttpLoggingInterceptor.Level.BODY); - dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.of("UTC")); + dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.of("GMT")); try { digest = MessageDigest.getInstance("SHA-256"); @@ -202,11 +202,11 @@ private Request buildRequest(Token token, final AbstractRequest req) { Instant timestamp = Instant.now(); + String formattedDate = dateTimeFormatter.format(timestamp); request.addHeader("Accept-Encoding", "gzip, deflate").addHeader("Accept", "*/*") .addHeader("User-Agent", "G-RAC").addHeader("Content-Type", "application/json;charset=utf-8") - .addHeader("x-app-name", "Comfort Cloud") - .addHeader("x-app-timestamp", dateTimeFormatter.format(timestamp)).addHeader("x-app-type", "1") - .addHeader("x-app-version", appVersion) + .addHeader("x-app-name", "Comfort Cloud").addHeader("x-app-timestamp", formattedDate) + .addHeader("x-app-type", "1").addHeader("x-app-version", appVersion) .addHeader("x-cfc-api-key", generateAPIKey(timestamp, token.getAccessToken())) .addHeader("x-user-authorization-v2", "Bearer " + token.getAccessToken()) .addHeader("x-client-id", token.getClientId()).build(); @@ -401,10 +401,11 @@ private Token doV2AuthorizationFlow() throws IOException, NoSuchAlgorithmExcepti RequestBody body = RequestBody.create(MediaType.parse("application/json;charset=utf-8"), gson.toJson(new GetAccClientIdDTO())); + String formattedDate = dateTimeFormatter.format(now); Request getAccClientIdRequest = new Request.Builder().post(body).url(BASE_PATH_ACC + "/auth/v2/login") .addHeader("Accept-Encoding", "gzip, deflate").addHeader("Accept", "*/*") .addHeader("User-Agent", "G-RAC").addHeader("Content-Type", "application/json;charset=utf-8") - .addHeader("x-app-name", "Comfort Cloud").addHeader("x-app-timestamp", dateTimeFormatter.format(now)) + .addHeader("x-app-name", "Comfort Cloud").addHeader("x-app-timestamp", formattedDate) .addHeader("x-app-type", "1").addHeader("x-app-version", appVersion) .addHeader("x-cfc-api-key", generateAPIKey(now, accessToken)) .addHeader("x-user-authorization-v2", "Bearer " + accessToken).build(); diff --git a/src/main/java/no/seime/openhab/binding/panasoniccomfortcloud/internal/handler/PanasonicComfortCloudAccountHandler.java b/src/main/java/no/seime/openhab/binding/panasoniccomfortcloud/internal/handler/PanasonicComfortCloudAccountHandler.java index 091e66a..8d86afd 100644 --- a/src/main/java/no/seime/openhab/binding/panasoniccomfortcloud/internal/handler/PanasonicComfortCloudAccountHandler.java +++ b/src/main/java/no/seime/openhab/binding/panasoniccomfortcloud/internal/handler/PanasonicComfortCloudAccountHandler.java @@ -14,8 +14,10 @@ package no.seime.openhab.binding.panasoniccomfortcloud.internal.handler; import java.util.Optional; +import java.util.Random; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; import org.apache.commons.lang3.StringUtils; import org.eclipse.jdt.annotation.NonNullByDefault; @@ -63,6 +65,8 @@ public class PanasonicComfortCloudAccountHandler extends BaseBridgeHandler { private static final String STORAGE_KEY = "PanasonicComfortCloud-Storage"; + private Random random = new Random(); + public PanasonicComfortCloudAccountHandler(final Bridge bridge, StorageService storageService) { super(bridge); apiBridge = new ApiBridge(storageService.getStorage(STORAGE_KEY)); @@ -146,13 +150,18 @@ public synchronized void doPoll(boolean triggerDeviceUpdate) { } updateStatus(ThingStatus.ONLINE); if (triggerDeviceUpdate) { + + AtomicLong delayIncrementer = new AtomicLong(1000); + try { - getThing().getThings().parallelStream() + getThing().getThings().stream() .filter(e -> e.isEnabled() && (e.getStatus() == ThingStatus.ONLINE || e.getStatus() == ThingStatus.OFFLINE)) .forEach(e -> { + long delay = delayIncrementer.addAndGet(random.nextLong(3000)); try { - ((PanasonicComfortCloudBaseThingHandler) e.getHandler()).loadFromServer(); + scheduler.schedule(() -> ((PanasonicComfortCloudBaseThingHandler) e.getHandler()) + .loadFromServer(), delay, TimeUnit.MILLISECONDS); } catch (Exception ex) { logger.warn("Error updating thing {}", e.getUID(), ex); } diff --git a/src/main/java/no/seime/openhab/binding/panasoniccomfortcloud/internal/handler/PanasonicComfortCloudAirconditionHandler.java b/src/main/java/no/seime/openhab/binding/panasoniccomfortcloud/internal/handler/PanasonicComfortCloudAirconditionHandler.java index 3048d89..1437a38 100644 --- a/src/main/java/no/seime/openhab/binding/panasoniccomfortcloud/internal/handler/PanasonicComfortCloudAirconditionHandler.java +++ b/src/main/java/no/seime/openhab/binding/panasoniccomfortcloud/internal/handler/PanasonicComfortCloudAirconditionHandler.java @@ -16,6 +16,7 @@ import static no.seime.openhab.binding.panasoniccomfortcloud.internal.BindingConstants.*; import java.util.Optional; +import java.util.Random; import java.util.concurrent.TimeUnit; import javax.measure.quantity.Temperature; @@ -55,6 +56,8 @@ public PanasonicComfortCloudAirconditionHandler(Thing thing) { super(thing); } + private Random random = new Random(); + private AirConditionerConfiguration config; @Override @@ -65,7 +68,7 @@ public void initialize() { super.initialize(config.deviceId); // This handler is responsible for loading the first time from the server, then the Account handler will take // over - scheduler.schedule(this::loadIfDevicePresent, 3, TimeUnit.SECONDS); + scheduler.schedule(this::loadIfDevicePresent, 3 + random.nextInt(10), TimeUnit.SECONDS); } private void loadIfDevicePresent() {