diff --git a/bundles/org.openhab.binding.heos/src/main/java/org/openhab/binding/heos/internal/handler/HeosBridgeHandler.java b/bundles/org.openhab.binding.heos/src/main/java/org/openhab/binding/heos/internal/handler/HeosBridgeHandler.java index 986aea3bb..5ad0f7c57 100644 --- a/bundles/org.openhab.binding.heos/src/main/java/org/openhab/binding/heos/internal/handler/HeosBridgeHandler.java +++ b/bundles/org.openhab.binding.heos/src/main/java/org/openhab/binding/heos/internal/handler/HeosBridgeHandler.java @@ -28,6 +28,7 @@ import java.util.Optional; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @@ -52,6 +53,7 @@ import org.openhab.binding.heos.internal.json.payload.Group; import org.openhab.binding.heos.internal.json.payload.Media; import org.openhab.binding.heos.internal.json.payload.Player; import org.openhab.binding.heos.internal.resources.HeosEventListener; +import org.openhab.binding.heos.internal.resources.HeosMediaEventListener; import org.openhab.binding.heos.internal.resources.Telnet; import org.openhab.binding.heos.internal.resources.Telnet.ReadException; import org.openhab.core.library.types.OnOffType; @@ -77,6 +79,7 @@ import org.slf4j.LoggerFactory; * sent to one of the channels. * * @author Johannes Einig - Initial contribution + * @author Martin van Wingerden - change handling of stop/pause depending on playing item type */ @NonNullByDefault public class HeosBridgeHandler extends BaseBridgeHandler implements HeosEventListener { @@ -84,6 +87,7 @@ public class HeosBridgeHandler extends BaseBridgeHandler implements HeosEventLis private static final int HEOS_PORT = 1255; + private final Set heosMediaEventListeners = new CopyOnWriteArraySet<>(); private final List playerDiscoveryList = new CopyOnWriteArrayList<>(); private final HeosChannelManager channelManager = new HeosChannelManager(this); private final HeosChannelHandlerFactory channelHandlerFactory; @@ -408,7 +412,7 @@ public class HeosBridgeHandler extends BaseBridgeHandler implements HeosEventLis @Override public void playerMediaChangeEvent(String pid, Media media) { - // do nothing + heosMediaEventListeners.forEach(element -> element.playerMediaChangeEvent(pid, media)); } @Override @@ -518,4 +522,8 @@ public class HeosBridgeHandler extends BaseBridgeHandler implements HeosEventLis public Collection> getServices() { return Collections.singletonList(HeosActions.class); } + + public void registerMediaEventListener(HeosMediaEventListener heosMediaEventListener) { + heosMediaEventListeners.add(heosMediaEventListener); + } } diff --git a/bundles/org.openhab.binding.heos/src/main/java/org/openhab/binding/heos/internal/handler/HeosChannelHandlerControl.java b/bundles/org.openhab.binding.heos/src/main/java/org/openhab/binding/heos/internal/handler/HeosChannelHandlerControl.java index 3fcfede25..8b0945233 100644 --- a/bundles/org.openhab.binding.heos/src/main/java/org/openhab/binding/heos/internal/handler/HeosChannelHandlerControl.java +++ b/bundles/org.openhab.binding.heos/src/main/java/org/openhab/binding/heos/internal/handler/HeosChannelHandlerControl.java @@ -12,12 +12,18 @@ */ package org.openhab.binding.heos.internal.handler; +import static org.openhab.binding.heos.internal.resources.HeosConstants.SONG; + import java.io.IOException; +import java.util.HashMap; +import java.util.Map; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.openhab.binding.heos.internal.exception.HeosNotFoundException; +import org.openhab.binding.heos.internal.json.payload.Media; import org.openhab.binding.heos.internal.resources.HeosEventListener; +import org.openhab.binding.heos.internal.resources.HeosMediaEventListener; import org.openhab.binding.heos.internal.resources.Telnet.ReadException; import org.openhab.core.thing.ThingUID; import org.openhab.core.types.Command; @@ -28,13 +34,16 @@ import org.openhab.core.types.RefreshType; * coming from the implementing thing * * @author Johannes Einig - Initial contribution + * @author Martin van Wingerden - change handling of stop/pause depending on playing item type */ @NonNullByDefault -public class HeosChannelHandlerControl extends BaseHeosChannelHandler { +public class HeosChannelHandlerControl extends BaseHeosChannelHandler implements HeosMediaEventListener { private final HeosEventListener eventListener; + private final Map playingMediaCache = new HashMap<>(); public HeosChannelHandlerControl(HeosEventListener eventListener, HeosBridgeHandler bridge) { super(bridge); + bridge.registerMediaEventListener(this); this.eventListener = eventListener; } @@ -69,7 +78,11 @@ public class HeosChannelHandlerControl extends BaseHeosChannelHandler { break; case "PAUSE": case "OFF": - getApi().pause(id); + if (shouldPause(id)) { + getApi().pause(id); + } else { + getApi().stop(id); + } break; case "NEXT": getApi().next(id); @@ -79,4 +92,28 @@ public class HeosChannelHandlerControl extends BaseHeosChannelHandler { break; } } + + private boolean shouldPause(String id) { + Media applicableMedia = playingMediaCache.get(id); + if (applicableMedia == null || SONG.equals(applicableMedia.type)) { + return true; + } else { + // we have a station here, just have to check which one + switch (applicableMedia.sourceId) { + case Media.SOURCE_TUNE_IN: + case Media.SOURCE_I_HEART_RADIO: + case Media.SOURCE_SIRIUS_XM: + case Media.SOURCE_AUX: + return false; + + default: + return true; + } + } + } + + @Override + public void playerMediaChangeEvent(String pid, Media media) { + playingMediaCache.put(pid, media); + } } diff --git a/bundles/org.openhab.binding.heos/src/main/java/org/openhab/binding/heos/internal/json/payload/Media.java b/bundles/org.openhab.binding.heos/src/main/java/org/openhab/binding/heos/internal/json/payload/Media.java index 4342f3dae..1b78ed13c 100644 --- a/bundles/org.openhab.binding.heos/src/main/java/org/openhab/binding/heos/internal/json/payload/Media.java +++ b/bundles/org.openhab.binding.heos/src/main/java/org/openhab/binding/heos/internal/json/payload/Media.java @@ -24,6 +24,31 @@ import com.google.gson.annotations.SerializedName; */ @NonNullByDefault public class Media { + public static final int SOURCE_PANDORA = 1; + public static final int SOURCE_RHAPSODY = 2; + public static final int SOURCE_TUNE_IN = 3; + public static final int SOURCE_SPOTIFY = 4; + public static final int SOURCE_DEEZER = 5; + public static final int SOURCE_NAPSTER = 6; + public static final int SOURCE_I_HEART_RADIO = 7; + public static final int SOURCE_SIRIUS_XM = 8; + public static final int SOURCE_SOUNDCLOUD = 9; + public static final int SOURCE_TIDAL = 10; + // public static final int SOURCE_FUTURE_SERVICE = 11; + public static final int SOURCE_RDIO = 12; + public static final int SOURCE_AMAZON_MUSIC = 13; + // public static final int SOURCE_FUTURE_SERVICE = 14; + public static final int SOURCE_MOODMIX = 15; + public static final int SOURCE_JUKE = 16; + // public static final int SOURCE_FUTURE_SERVICE = 17; + public static final int SOURCE_Q_Q_MUSIC = 18; + + public static final int SOURCE_LOCAL = 1024; + public static final int SOURCE_PLAYLIST = 1025; + public static final int SOURCE_HISTORY = 1026; + public static final int SOURCE_AUX = 1027; + public static final int SOURCE_FAVORITES = 1028; + public @Nullable String type; public @Nullable String song; public @Nullable String station; diff --git a/bundles/org.openhab.binding.heos/src/main/java/org/openhab/binding/heos/internal/resources/HeosEventListener.java b/bundles/org.openhab.binding.heos/src/main/java/org/openhab/binding/heos/internal/resources/HeosEventListener.java index 75e0492f4..cada2a092 100644 --- a/bundles/org.openhab.binding.heos/src/main/java/org/openhab/binding/heos/internal/resources/HeosEventListener.java +++ b/bundles/org.openhab.binding.heos/src/main/java/org/openhab/binding/heos/internal/resources/HeosEventListener.java @@ -12,14 +12,11 @@ */ package org.openhab.binding.heos.internal.resources; -import java.util.EventListener; - import org.eclipse.jdt.annotation.NonNullByDefault; import org.openhab.binding.heos.internal.api.HeosEventController; import org.openhab.binding.heos.internal.exception.HeosFunctionalException; import org.openhab.binding.heos.internal.json.dto.HeosEventObject; import org.openhab.binding.heos.internal.json.dto.HeosResponseObject; -import org.openhab.binding.heos.internal.json.payload.Media; /** * The {@link HeosEventListener } is an Event Listener @@ -28,15 +25,14 @@ import org.openhab.binding.heos.internal.json.payload.Media; * implement this class and register itself at the {@link HeosEventController} * * @author Johannes Einig - Initial contribution + * @author Martin van Wingerden - change handling of stop/pause depending on playing item type */ @NonNullByDefault -public interface HeosEventListener extends EventListener { +public interface HeosEventListener extends HeosMediaEventListener { void playerStateChangeEvent(HeosEventObject eventObject); void playerStateChangeEvent(HeosResponseObject responseObject) throws HeosFunctionalException; - void playerMediaChangeEvent(String pid, Media media); - void bridgeChangeEvent(String event, boolean success, Object command); } diff --git a/bundles/org.openhab.binding.heos/src/main/java/org/openhab/binding/heos/internal/resources/HeosMediaEventListener.java b/bundles/org.openhab.binding.heos/src/main/java/org/openhab/binding/heos/internal/resources/HeosMediaEventListener.java new file mode 100644 index 000000000..66b0514fc --- /dev/null +++ b/bundles/org.openhab.binding.heos/src/main/java/org/openhab/binding/heos/internal/resources/HeosMediaEventListener.java @@ -0,0 +1,35 @@ +/** + * 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.heos.internal.resources; + +import java.util.EventListener; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.binding.heos.internal.api.HeosEventController; +import org.openhab.binding.heos.internal.handler.HeosBridgeHandler; +import org.openhab.binding.heos.internal.json.payload.Media; + +/** + * The {@link HeosMediaEventListener } is a dedicated Event Listener + * for the HEOS media events. Handler which wants the get informed + * by an HEOS media event via the {@link HeosEventController} has to + * implement this class and register itself either at the + * {@link HeosEventController} or at {@link HeosBridgeHandler} + * + * @author Martin van Wingerden - Initial contribution + */ +@NonNullByDefault +public interface HeosMediaEventListener extends EventListener { + + void playerMediaChangeEvent(String pid, Media media); +} diff --git a/bundles/org.openhab.binding.heos/src/main/java/org/openhab/binding/heos/internal/resources/HeosSystemEventListener.java b/bundles/org.openhab.binding.heos/src/main/java/org/openhab/binding/heos/internal/resources/HeosSystemEventListener.java index 415b518b4..9b4f3b5df 100644 --- a/bundles/org.openhab.binding.heos/src/main/java/org/openhab/binding/heos/internal/resources/HeosSystemEventListener.java +++ b/bundles/org.openhab.binding.heos/src/main/java/org/openhab/binding/heos/internal/resources/HeosSystemEventListener.java @@ -27,10 +27,11 @@ import org.openhab.binding.heos.internal.json.payload.Media; * the class which extends this {@link HeosSystemEventListener} * * @author Johannes Einig - Initial contribution + * @author Martin van Wingerden - change handling of stop/pause depending on playing item type */ @NonNullByDefault public class HeosSystemEventListener { - private Set listenerList = new CopyOnWriteArraySet<>(); + private final Set listenerList = new CopyOnWriteArraySet<>(); /** * Register a listener from type {@link HeosEventListener} to be notified by