diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/AnnouncementTargetDeviceTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/DeviceIdTO.java similarity index 78% rename from bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/AnnouncementTargetDeviceTO.java rename to bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/DeviceIdTO.java index 9362bc3d46..37e1c9eada 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/AnnouncementTargetDeviceTO.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/DeviceIdTO.java @@ -10,16 +10,16 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.smarthomej.binding.amazonechocontrol.internal.dto.request; +package org.smarthomej.binding.amazonechocontrol.internal.dto; import org.eclipse.jdt.annotation.NonNull; /** - * The {@link AnnouncementTargetDeviceTO} encapsulates a target device for an announcement target + * The {@link DeviceIdTO} encapsulates a target device for an announcement target * * @author Jan N. Klug - Initial contribution */ -public class AnnouncementTargetDeviceTO { +public class DeviceIdTO { public String deviceSerialNumber; public String deviceTypeId; diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/TOMapper.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/TOMapper.java index 282821daec..542112d23d 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/TOMapper.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/TOMapper.java @@ -25,7 +25,6 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; -import org.smarthomej.binding.amazonechocontrol.internal.dto.request.AnnouncementTargetDeviceTO; import org.smarthomej.binding.amazonechocontrol.internal.types.Notification; import com.google.gson.Gson; @@ -51,8 +50,8 @@ public static Map mapToMap(Gson gson, Object o) { return Objects.requireNonNullElse(gson.fromJson(json, MAP_TYPE_TOKEN), Map.of()); } - public static AnnouncementTargetDeviceTO mapAnnouncementTargetDevice(DeviceTO device) { - AnnouncementTargetDeviceTO targetDevice = new AnnouncementTargetDeviceTO(); + public static DeviceIdTO mapAnnouncementTargetDevice(DeviceTO device) { + DeviceIdTO targetDevice = new DeviceIdTO(); targetDevice.deviceTypeId = device.deviceType; targetDevice.deviceSerialNumber = device.serialNumber; return targetDevice; diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/AnnouncementTargetTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/AnnouncementTargetTO.java index fd323ffb81..0fe6ee004f 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/AnnouncementTargetTO.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/request/AnnouncementTargetTO.java @@ -15,6 +15,7 @@ import java.util.List; import org.eclipse.jdt.annotation.NonNull; +import org.smarthomej.binding.amazonechocontrol.internal.dto.DeviceIdTO; /** * The {@link AnnouncementTargetTO} encapsulate the target section of an announcement @@ -23,7 +24,7 @@ */ public class AnnouncementTargetTO { public String customerId; - public List devices = List.of(); + public List devices = List.of(); @Override public @NonNull String toString() { diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/EligibilityTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/EligibilityTO.java new file mode 100644 index 0000000000..acf1532d6d --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/EligibilityTO.java @@ -0,0 +1,30 @@ +/** + * 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.amazonechocontrol.internal.dto.response; + +import org.eclipse.jdt.annotation.NonNull; + +/** + * The {@link EligibilityTO} encapsulates the eligibility section of a media session + * + * @author Jan N. Klug - Initial contribution + */ +public class EligibilityTO { + public boolean isEligible; + public String reasonCode; + + @Override + public @NonNull String toString() { + return "EligibilityTO{isEligible=" + isEligible + ", reasonCode='" + reasonCode + "'}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/ListMediaSessionTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/ListMediaSessionTO.java new file mode 100644 index 0000000000..a04ce9305b --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/ListMediaSessionTO.java @@ -0,0 +1,31 @@ +/** + * 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.amazonechocontrol.internal.dto.response; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNull; + +/** + * The {@link ListMediaSessionTO} encapsulates the response to /api/np/list-media.sessions + * + * @author Jan N. Klug - Initial contribution + */ +public class ListMediaSessionTO { + public List mediaSessionList = List.of(); + + @Override + public @NonNull String toString() { + return "ListMediaSessionTO{mediaSessionList=" + mediaSessionList + "}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/MediaSessionEndpointTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/MediaSessionEndpointTO.java new file mode 100644 index 0000000000..ce6d33ac09 --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/MediaSessionEndpointTO.java @@ -0,0 +1,36 @@ +/** + * 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.amazonechocontrol.internal.dto.response; + +import org.eclipse.jdt.annotation.NonNull; +import org.smarthomej.binding.amazonechocontrol.internal.dto.DeviceIdTO; + +import com.google.gson.annotations.SerializedName; + +/** + * The {@link MediaSessionEndpointTO} encapsulates a single endpoint information for a media session + * + * @author Jan N. Klug - Initial contribution + */ +public class MediaSessionEndpointTO { + @SerializedName("__type") + public String type; + public String encryptedFriendlyName; + public DeviceIdTO id; + + @Override + public @NonNull String toString() { + return "MediaSessionEndpointTO{type='" + type + "', encryptedFriendlyName='" + encryptedFriendlyName + "', id=" + + id + "}"; + } +} diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/MediaSessionTO.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/MediaSessionTO.java new file mode 100644 index 0000000000..bbd349d184 --- /dev/null +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/dto/response/MediaSessionTO.java @@ -0,0 +1,35 @@ +/** + * 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.amazonechocontrol.internal.dto.response; + +import java.util.List; + +import org.eclipse.jdt.annotation.NonNull; +import org.smarthomej.binding.amazonechocontrol.internal.dto.PlayerStateInfoTO; + +/** + * The {@link MediaSessionTO} encapsulates a single media session + * + * @author Jan N. Klug - Initial contribution + */ +public class MediaSessionTO { + public EligibilityTO castEligibility; + public List endpointList = List.of(); + public PlayerStateInfoTO nowPlayingData; + + @Override + public @NonNull String toString() { + return "MediaSessionTO{castEligibility=" + castEligibility + ", endpointList=" + endpointList + + ", nowPlayingData=" + nowPlayingData + "}"; + } +} 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 e764e51367..1eb4b1a1a8 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 @@ -661,7 +661,8 @@ public void onPushCommandReceived(PushCommandTO pushCommand) { break; case "NotifyMediaSessionsUpdated": // we can't determine which session was updated, but it only makes sense for currently playing devices - echoHandlers.forEach(e -> e.refreshAudioPlayerState(true)); + // echoHandlers.forEach(e -> e.refreshAudioPlayerState(true)); + echoHandlers.forEach(EchoHandler::updateMediaSessions); break; default: logger.warn("Detected unknown command from activity stream: {}", pushCommand); diff --git a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/handler/EchoHandler.java b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/handler/EchoHandler.java index f070a05a1f..ac076bf6ff 100644 --- a/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/handler/EchoHandler.java +++ b/bundles/org.smarthomej.binding.amazonechocontrol/src/main/java/org/smarthomej/binding/amazonechocontrol/internal/handler/EchoHandler.java @@ -88,6 +88,8 @@ import org.smarthomej.binding.amazonechocontrol.internal.dto.response.BluetoothStateTO; import org.smarthomej.binding.amazonechocontrol.internal.dto.response.CustomerHistoryRecordTO; import org.smarthomej.binding.amazonechocontrol.internal.dto.response.CustomerHistoryRecordVoiceTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.response.ListMediaSessionTO; +import org.smarthomej.binding.amazonechocontrol.internal.dto.response.MediaSessionTO; import org.smarthomej.binding.amazonechocontrol.internal.dto.response.MusicProviderTO; import org.smarthomej.binding.amazonechocontrol.internal.dto.response.PlayerStateTO; import org.smarthomej.binding.amazonechocontrol.internal.types.Notification; @@ -953,6 +955,30 @@ public void handleNowPlayingUpdated(PlayerStateInfoTO playerState) { } } + public void updateMediaSessions() { + findConnection().ifPresent(connection -> { + try { + DeviceTO device = this.device; + if (device == null || !isPlaying) { + return; + } + String url = connection.getAlexaServer() + "/api/np/list-media-sessions?deviceSerialNumber=" + + device.serialNumber + "&deviceType=" + device.deviceType; + List mediaSessions = connection.getRequestBuilder().get(url) + .syncSend(ListMediaSessionTO.class).mediaSessionList; + for (MediaSessionTO mediaSession : mediaSessions) { + if (findIn(mediaSession.endpointList, e -> e.id.deviceSerialNumber, device.serialNumber) + .isPresent()) { + updateMediaPlayerState(mediaSession.nowPlayingData, connection.isSequenceNodeQueueRunning(), + 1000); + } + } + } catch (ConnectionException e) { + logger.warn("Failed to update media sessions for {}: {}", thing.getUID(), e.getMessage()); + } + }); + } + /** * Refresh the audio player state *