From 4b20d7fdfc0662ea1893ffb6e6a482cd368ce043 Mon Sep 17 00:00:00 2001 From: Trinitus01 Date: Mon, 19 Feb 2024 23:30:40 +0100 Subject: [PATCH 1/6] fixed: missing Content-Length header (BodyPublisher.ofByteArrays JDK 17 issue) Signed-off-by: Tom Blum trinitus01@googlemail.com --- .../NotificationsForFireTVConnection.java | 243 +++++++++--------- 1 file changed, 127 insertions(+), 116 deletions(-) diff --git a/bundles/org.smarthomej.binding.notificationsforfiretv/src/main/java/org/smarthomej/binding/notificationsforfiretv/internal/NotificationsForFireTVConnection.java b/bundles/org.smarthomej.binding.notificationsforfiretv/src/main/java/org/smarthomej/binding/notificationsforfiretv/internal/NotificationsForFireTVConnection.java index 2bede8f999..43f0d2d784 100644 --- a/bundles/org.smarthomej.binding.notificationsforfiretv/src/main/java/org/smarthomej/binding/notificationsforfiretv/internal/NotificationsForFireTVConnection.java +++ b/bundles/org.smarthomej.binding.notificationsforfiretv/src/main/java/org/smarthomej/binding/notificationsforfiretv/internal/NotificationsForFireTVConnection.java @@ -1,116 +1,127 @@ -/** - * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.notificationsforfiretv.internal; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.net.HttpURLConnection; -import java.net.URI; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpRequest.BodyPublishers; -import java.net.http.HttpResponse; -import java.net.http.HttpResponse.BodyHandlers; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -import org.eclipse.jdt.annotation.NonNullByDefault; - -/** - * - * @author Tom Blum - Initial contribution - */ -@NonNullByDefault -public class NotificationsForFireTVConnection { - - private static final String PROTOCOL = "http"; - private static final String LINE = "\r\n"; - private static final String QUOTE = "\""; - - private URI uri; - private String boundary; - private HttpClient httpClient; - private List byteArrays = new ArrayList<>(); - - /** - * This constructor initializes a new HTTP POST request with content - * type is set to multipart/form-data - * - * @param hostname device IP address or a FQDN - * @param port application port - * @throws IOException - */ - public NotificationsForFireTVConnection(String hostname, int port) throws IOException { - uri = URI.create(PROTOCOL + "://" + hostname + ":" + port); - boundary = UUID.randomUUID().toString(); - httpClient = HttpClient.newBuilder().build(); - } - - /** - * Adds a form field to the request - * - * @param name field name - * @param value field value - */ - public void addFormField(String name, String value) { - byteArrays.add( - ("--" + boundary + LINE + "Content-Disposition: form-data; name=").getBytes(StandardCharsets.UTF_8)); - byteArrays.add((QUOTE + name + QUOTE + LINE + LINE + value + LINE).getBytes(StandardCharsets.UTF_8)); - } - - /** - * Adds a upload file section to the request - * - * @param name field name - * @param file file value - * @throws IOException - */ - public void addFilePart(String name, File file) throws IOException { - if (!file.exists()) { - throw new FileNotFoundException("File not found: " + file.getPath()); - } - - byteArrays.add( - ("--" + boundary + LINE + "Content-Disposition: form-data; name=").getBytes(StandardCharsets.UTF_8)); - byteArrays.add((QUOTE + name + QUOTE + "; filename=" + QUOTE + file.toPath().getFileName() + QUOTE + LINE - + "Content-Type: application/octet-stream" + LINE + LINE).getBytes(StandardCharsets.UTF_8)); - byteArrays.add(Files.readAllBytes(file.toPath())); - byteArrays.add(LINE.getBytes(StandardCharsets.UTF_8)); - } - - /** - * Completes the request and receives response from the server. - * - * @return String as response in case the server returned status OK, - * otherwise an exception is thrown. - * @throws IOException - * @throws InterruptedException - */ - public String send() throws IOException, InterruptedException { - byteArrays.add(("--" + boundary + "--").getBytes(StandardCharsets.UTF_8)); - - HttpRequest httpRequest = HttpRequest.newBuilder() - .header("Content-Type", "multipart/form-data;boundary=" + boundary) - .POST(BodyPublishers.ofByteArrays(byteArrays)).uri(uri).build(); - HttpResponse response = httpClient.send(httpRequest, BodyHandlers.ofString()); - if (response.statusCode() == HttpURLConnection.HTTP_OK) { - return response.body(); - } else { - throw new IOException("Unable to connect to server: " + response.statusCode()); - } - } -} +/** + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.notificationsforfiretv.internal; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpRequest.BodyPublisher; +import java.net.http.HttpRequest.BodyPublishers; +import java.net.http.HttpResponse; +import java.net.http.HttpResponse.BodyHandlers; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author Tom Blum - Initial contribution + */ +@NonNullByDefault +public class NotificationsForFireTVConnection { + + private static final String PROTOCOL = "http"; + private static final String LINE = "\r\n"; + private static final String QUOTE = "\""; + + private URI uri; + private String boundary; + private HttpClient httpClient; + private List byteArrays = new ArrayList<>(); + + private final Logger logger = LoggerFactory.getLogger(NotificationsForFireTVConnection.class); + + /** + * This constructor initializes a new HTTP POST request with content + * type is set to multipart/form-data + * + * @param hostname device IP address or a FQDN + * @param port application port + * @throws IOException + */ + public NotificationsForFireTVConnection(String hostname, int port) throws IOException { + uri = URI.create(PROTOCOL + "://" + hostname + ":" + port); + boundary = UUID.randomUUID().toString(); + httpClient = HttpClient.newBuilder().build(); + } + + /** + * Adds a form field to the request + * + * @param name field name + * @param value field value + */ + public void addFormField(String name, String value) { + byteArrays.add( + ("--" + boundary + LINE + "Content-Disposition: form-data; name=").getBytes(StandardCharsets.UTF_8)); + byteArrays.add((QUOTE + name + QUOTE + LINE + LINE + value + LINE).getBytes(StandardCharsets.UTF_8)); + } + + /** + * Adds a upload file section to the request + * + * @param name field name + * @param file file value + * @throws IOException + */ + public void addFilePart(String name, File file) throws IOException { + if (!file.exists()) { + throw new FileNotFoundException("File not found: " + file.getPath()); + } + + byteArrays.add( + ("--" + boundary + LINE + "Content-Disposition: form-data; name=").getBytes(StandardCharsets.UTF_8)); + byteArrays.add((QUOTE + name + QUOTE + "; filename=" + QUOTE + file.toPath().getFileName() + QUOTE + LINE + + "Content-Type: application/octet-stream" + LINE + LINE).getBytes(StandardCharsets.UTF_8)); + byteArrays.add(Files.readAllBytes(file.toPath())); + byteArrays.add(LINE.getBytes(StandardCharsets.UTF_8)); + } + + /** + * Completes the request and receives response from the server. + * + * @return String as response in case the server returned status OK, + * otherwise an exception is thrown. + * @throws IOException + * @throws InterruptedException + */ + public String send() throws IOException, InterruptedException { + byteArrays.add(("--" + boundary + "--").getBytes(StandardCharsets.UTF_8)); + + int length = 0; + for (byte[] bytes : byteArrays) { + length += bytes.length; + } + + BodyPublisher bodyPublisher = BodyPublishers.fromPublisher(BodyPublishers.ofByteArrays(byteArrays), length); + HttpRequest httpRequest = HttpRequest.newBuilder() + .header("Content-Type", "multipart/form-data;boundary=" + boundary).POST(bodyPublisher).uri(uri) + .build(); + HttpResponse response = httpClient.send(httpRequest, BodyHandlers.ofString()); + if (response.statusCode() == HttpURLConnection.HTTP_OK) { + return response.body(); + } else { + throw new IOException("Unable to connect to server: " + response.statusCode()); + } + } +} From 92bd0d0adfad1da5049e9a596664227fcdd6eae8 Mon Sep 17 00:00:00 2001 From: Trinitus01 Date: Mon, 19 Feb 2024 23:40:11 +0100 Subject: [PATCH 2/6] fixed: commited line endings Signed-off-by: Tom Blum trinitus01@googlemail.com --- .../NotificationsForFireTVConnection.java | 254 +++++++++--------- 1 file changed, 127 insertions(+), 127 deletions(-) diff --git a/bundles/org.smarthomej.binding.notificationsforfiretv/src/main/java/org/smarthomej/binding/notificationsforfiretv/internal/NotificationsForFireTVConnection.java b/bundles/org.smarthomej.binding.notificationsforfiretv/src/main/java/org/smarthomej/binding/notificationsforfiretv/internal/NotificationsForFireTVConnection.java index 43f0d2d784..8d25b36bfc 100644 --- a/bundles/org.smarthomej.binding.notificationsforfiretv/src/main/java/org/smarthomej/binding/notificationsforfiretv/internal/NotificationsForFireTVConnection.java +++ b/bundles/org.smarthomej.binding.notificationsforfiretv/src/main/java/org/smarthomej/binding/notificationsforfiretv/internal/NotificationsForFireTVConnection.java @@ -1,127 +1,127 @@ -/** - * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.notificationsforfiretv.internal; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.net.HttpURLConnection; -import java.net.URI; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpRequest.BodyPublisher; -import java.net.http.HttpRequest.BodyPublishers; -import java.net.http.HttpResponse; -import java.net.http.HttpResponse.BodyHandlers; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -import org.eclipse.jdt.annotation.NonNullByDefault; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * - * @author Tom Blum - Initial contribution - */ -@NonNullByDefault -public class NotificationsForFireTVConnection { - - private static final String PROTOCOL = "http"; - private static final String LINE = "\r\n"; - private static final String QUOTE = "\""; - - private URI uri; - private String boundary; - private HttpClient httpClient; - private List byteArrays = new ArrayList<>(); - - private final Logger logger = LoggerFactory.getLogger(NotificationsForFireTVConnection.class); - - /** - * This constructor initializes a new HTTP POST request with content - * type is set to multipart/form-data - * - * @param hostname device IP address or a FQDN - * @param port application port - * @throws IOException - */ - public NotificationsForFireTVConnection(String hostname, int port) throws IOException { - uri = URI.create(PROTOCOL + "://" + hostname + ":" + port); - boundary = UUID.randomUUID().toString(); - httpClient = HttpClient.newBuilder().build(); - } - - /** - * Adds a form field to the request - * - * @param name field name - * @param value field value - */ - public void addFormField(String name, String value) { - byteArrays.add( - ("--" + boundary + LINE + "Content-Disposition: form-data; name=").getBytes(StandardCharsets.UTF_8)); - byteArrays.add((QUOTE + name + QUOTE + LINE + LINE + value + LINE).getBytes(StandardCharsets.UTF_8)); - } - - /** - * Adds a upload file section to the request - * - * @param name field name - * @param file file value - * @throws IOException - */ - public void addFilePart(String name, File file) throws IOException { - if (!file.exists()) { - throw new FileNotFoundException("File not found: " + file.getPath()); - } - - byteArrays.add( - ("--" + boundary + LINE + "Content-Disposition: form-data; name=").getBytes(StandardCharsets.UTF_8)); - byteArrays.add((QUOTE + name + QUOTE + "; filename=" + QUOTE + file.toPath().getFileName() + QUOTE + LINE - + "Content-Type: application/octet-stream" + LINE + LINE).getBytes(StandardCharsets.UTF_8)); - byteArrays.add(Files.readAllBytes(file.toPath())); - byteArrays.add(LINE.getBytes(StandardCharsets.UTF_8)); - } - - /** - * Completes the request and receives response from the server. - * - * @return String as response in case the server returned status OK, - * otherwise an exception is thrown. - * @throws IOException - * @throws InterruptedException - */ - public String send() throws IOException, InterruptedException { - byteArrays.add(("--" + boundary + "--").getBytes(StandardCharsets.UTF_8)); - - int length = 0; - for (byte[] bytes : byteArrays) { - length += bytes.length; - } - - BodyPublisher bodyPublisher = BodyPublishers.fromPublisher(BodyPublishers.ofByteArrays(byteArrays), length); - HttpRequest httpRequest = HttpRequest.newBuilder() - .header("Content-Type", "multipart/form-data;boundary=" + boundary).POST(bodyPublisher).uri(uri) - .build(); - HttpResponse response = httpClient.send(httpRequest, BodyHandlers.ofString()); - if (response.statusCode() == HttpURLConnection.HTTP_OK) { - return response.body(); - } else { - throw new IOException("Unable to connect to server: " + response.statusCode()); - } - } -} +/** + * Copyright (c) 2021-2023 Contributors to the SmartHome/J 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.smarthomej.binding.notificationsforfiretv.internal; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpRequest.BodyPublisher; +import java.net.http.HttpRequest.BodyPublishers; +import java.net.http.HttpResponse; +import java.net.http.HttpResponse.BodyHandlers; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author Tom Blum - Initial contribution + */ +@NonNullByDefault +public class NotificationsForFireTVConnection { + + private static final String PROTOCOL = "http"; + private static final String LINE = "\r\n"; + private static final String QUOTE = "\""; + + private URI uri; + private String boundary; + private HttpClient httpClient; + private List byteArrays = new ArrayList<>(); + + private final Logger logger = LoggerFactory.getLogger(NotificationsForFireTVConnection.class); + + /** + * This constructor initializes a new HTTP POST request with content + * type is set to multipart/form-data + * + * @param hostname device IP address or a FQDN + * @param port application port + * @throws IOException + */ + public NotificationsForFireTVConnection(String hostname, int port) throws IOException { + uri = URI.create(PROTOCOL + "://" + hostname + ":" + port); + boundary = UUID.randomUUID().toString(); + httpClient = HttpClient.newBuilder().build(); + } + + /** + * Adds a form field to the request + * + * @param name field name + * @param value field value + */ + public void addFormField(String name, String value) { + byteArrays.add( + ("--" + boundary + LINE + "Content-Disposition: form-data; name=").getBytes(StandardCharsets.UTF_8)); + byteArrays.add((QUOTE + name + QUOTE + LINE + LINE + value + LINE).getBytes(StandardCharsets.UTF_8)); + } + + /** + * Adds a upload file section to the request + * + * @param name field name + * @param file file value + * @throws IOException + */ + public void addFilePart(String name, File file) throws IOException { + if (!file.exists()) { + throw new FileNotFoundException("File not found: " + file.getPath()); + } + + byteArrays.add( + ("--" + boundary + LINE + "Content-Disposition: form-data; name=").getBytes(StandardCharsets.UTF_8)); + byteArrays.add((QUOTE + name + QUOTE + "; filename=" + QUOTE + file.toPath().getFileName() + QUOTE + LINE + + "Content-Type: application/octet-stream" + LINE + LINE).getBytes(StandardCharsets.UTF_8)); + byteArrays.add(Files.readAllBytes(file.toPath())); + byteArrays.add(LINE.getBytes(StandardCharsets.UTF_8)); + } + + /** + * Completes the request and receives response from the server. + * + * @return String as response in case the server returned status OK, + * otherwise an exception is thrown. + * @throws IOException + * @throws InterruptedException + */ + public String send() throws IOException, InterruptedException { + byteArrays.add(("--" + boundary + "--").getBytes(StandardCharsets.UTF_8)); + + int length = 0; + for (byte[] bytes : byteArrays) { + length += bytes.length; + } + + BodyPublisher bodyPublisher = BodyPublishers.fromPublisher(BodyPublishers.ofByteArrays(byteArrays), length); + HttpRequest httpRequest = HttpRequest.newBuilder() + .header("Content-Type", "multipart/form-data;boundary=" + boundary).POST(bodyPublisher).uri(uri) + .build(); + HttpResponse response = httpClient.send(httpRequest, BodyHandlers.ofString()); + if (response.statusCode() == HttpURLConnection.HTTP_OK) { + return response.body(); + } else { + throw new IOException("Unable to connect to server: " + response.statusCode()); + } + } +} From 55ac4f5c658364f6fa9effd2bba0238a7f42ba39 Mon Sep 17 00:00:00 2001 From: Trinitus01 Date: Mon, 19 Feb 2024 23:42:37 +0100 Subject: [PATCH 3/6] removed: logger Signed-off-by: Tom Blum trinitus01@googlemail.com --- .../internal/NotificationsForFireTVConnection.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/bundles/org.smarthomej.binding.notificationsforfiretv/src/main/java/org/smarthomej/binding/notificationsforfiretv/internal/NotificationsForFireTVConnection.java b/bundles/org.smarthomej.binding.notificationsforfiretv/src/main/java/org/smarthomej/binding/notificationsforfiretv/internal/NotificationsForFireTVConnection.java index 8d25b36bfc..970b8f5f6d 100644 --- a/bundles/org.smarthomej.binding.notificationsforfiretv/src/main/java/org/smarthomej/binding/notificationsforfiretv/internal/NotificationsForFireTVConnection.java +++ b/bundles/org.smarthomej.binding.notificationsforfiretv/src/main/java/org/smarthomej/binding/notificationsforfiretv/internal/NotificationsForFireTVConnection.java @@ -30,8 +30,6 @@ import java.util.UUID; import org.eclipse.jdt.annotation.NonNullByDefault; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * @@ -49,8 +47,6 @@ public class NotificationsForFireTVConnection { private HttpClient httpClient; private List byteArrays = new ArrayList<>(); - private final Logger logger = LoggerFactory.getLogger(NotificationsForFireTVConnection.class); - /** * This constructor initializes a new HTTP POST request with content * type is set to multipart/form-data From 472bd098df349a5c87af89372f20395bc771e712 Mon Sep 17 00:00:00 2001 From: Tom Blum Date: Fri, 4 Oct 2024 17:21:11 +0200 Subject: [PATCH 4/6] fixed: boken last voice command on Fire TV Cube Signed-off-by: Tom Blum --- .../internal/handler/AccountHandler.java | 39 +++++++++++++------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/handler/AccountHandler.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/handler/AccountHandler.java index 9edde261ed..73d8c73bca 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/handler/AccountHandler.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/handler/AccountHandler.java @@ -27,8 +27,11 @@ import java.time.chrono.ChronoZonedDateTime; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Objects; @@ -141,6 +144,8 @@ public class AccountHandler extends BaseBridgeHandler implements PushConnection. private boolean disposing = false; private @Nullable AccountTO accountInformation; + Set deviceSerialNumbers = Collections.synchronizedSet(new LinkedHashSet<>()); + public AccountHandler(Bridge bridge, Storage stateStorage, Gson gson, HttpClient httpClient, HTTP2Client http2Client, AmazonEchoControlCommandDescriptionProvider commandDescriptionProvider) { super(bridge); @@ -593,7 +598,8 @@ private EnabledFeedTO copyFeed(EnabledFeedTO feed) { public void onPushCommandReceived(PushCommandTO pushCommand) { logger.debug("Processing {}", pushCommand); String payload = pushCommand.payload; - switch (pushCommand.command) { + String command = pushCommand.command; + switch (command) { case "PUSH_ACTIVITY": // currently unused, seems to be removed, log a warning if it re-appears logger.warn("Activity detected: {}", pushCommand); @@ -624,15 +630,15 @@ public void onPushCommandReceived(PushCommandTO pushCommand) { if (echoHandler == null) { return; } - echoHandler.handlePushCommand(pushCommand.command, payload); - if ("PUSH_EQUALIZER_STATE_CHANGE".equals(pushCommand.command) - || "PUSH_VOLUME_CHANGE".equals(pushCommand.command)) { + echoHandler.handlePushCommand(command, payload); + if ("PUSH_EQUALIZER_STATE_CHANGE".equals(command) || "PUSH_VOLUME_CHANGE".equals(command)) { + deviceSerialNumbers.add(dopplerId.deviceSerialNumber); ScheduledFuture refreshActivityJob = this.refreshActivityJob; if (refreshActivityJob != null) { refreshActivityJob.cancel(false); } this.refreshActivityJob = scheduler.schedule( - () -> handlePushActivity(dopplerId.deviceSerialNumber, pushCommand.timeStamp), + () -> handlePushActivity(deviceSerialNumbers, pushCommand.timeStamp), handlerConfig.activityRequestDelay, TimeUnit.SECONDS); } } @@ -670,15 +676,24 @@ private List getCustomerActivity(@Nullable Long timesta return connection.getActivities(startTimestamp, endTimestamp); } - private void handlePushActivity(String deviceSerialNumber, @Nullable Long timestamp) { + private void handlePushActivity(Set deviceSerialNumbers, @Nullable Long timestamp) { List activityRecords = getCustomerActivity(timestamp); - EchoHandler echoHandler = echoHandlers.get(deviceSerialNumber); - if (echoHandler == null) { - logger.warn("Could not find thing handler for serialnumber {}", deviceSerialNumber); - return; + + Iterator iterator = deviceSerialNumbers.iterator(); + while (iterator.hasNext()) { + try { + String deviceSerialNumber = iterator.next(); + EchoHandler echoHandler = echoHandlers.get(deviceSerialNumber); + if (echoHandler == null) { + logger.warn("Could not find thing handler for serialnumber {}", deviceSerialNumber); + return; + } + activityRecords.stream().filter(r -> r.recordKey.endsWith(deviceSerialNumber)) + .forEach(echoHandler::handlePushActivity); + } finally { + iterator.remove(); + } } - activityRecords.stream().filter(r -> r.recordKey.endsWith(deviceSerialNumber)) - .forEach(echoHandler::handlePushActivity); } private @Nullable SmartHomeBaseDevice findSmartHomeDeviceJson(SmartHomeDeviceHandler handler) { From 0ee06ee687c75841b12905c83292459786188999 Mon Sep 17 00:00:00 2001 From: Tom Blum Date: Fri, 4 Oct 2024 17:40:01 +0200 Subject: [PATCH 5/6] fixed: spotless aso Signed-off-by: Tom Blum From 632e10188b23b86da651d17a804d857da3f0fae9 Mon Sep 17 00:00:00 2001 From: "Jan N. Klug" Date: Sun, 13 Oct 2024 10:16:54 +0200 Subject: [PATCH 6/6] review Signed-off-by: Jan N. Klug --- .../amazonechocontrol/internal/handler/AccountHandler.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/handler/AccountHandler.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/handler/AccountHandler.java index 73d8c73bca..e438b7e4a4 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/handler/AccountHandler.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/handler/AccountHandler.java @@ -27,11 +27,9 @@ import java.time.chrono.ChronoZonedDateTime; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; -import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Objects; @@ -118,6 +116,7 @@ public class AccountHandler extends BaseBridgeHandler implements PushConnection. private final Map echoHandlers = new ConcurrentHashMap<>(); private final Set smartHomeDeviceHandlers = new CopyOnWriteArraySet<>(); private final Set flashBriefingProfileHandlers = new CopyOnWriteArraySet<>(); + private final Set deviceSerialNumbers = new CopyOnWriteArraySet<>(); private final Object synchronizeConnection = new Object(); private Map serialNumberDeviceMapping = new HashMap<>(); @@ -144,8 +143,6 @@ public class AccountHandler extends BaseBridgeHandler implements PushConnection. private boolean disposing = false; private @Nullable AccountTO accountInformation; - Set deviceSerialNumbers = Collections.synchronizedSet(new LinkedHashSet<>()); - public AccountHandler(Bridge bridge, Storage stateStorage, Gson gson, HttpClient httpClient, HTTP2Client http2Client, AmazonEchoControlCommandDescriptionProvider commandDescriptionProvider) { super(bridge);