[HEOS] Update pause/stop handling (#9941)

Update PAUSE/STOP handling depending on the item that is currently playing.

Signed-off-by: Martin van Wingerden <martin@martinvw.nl>
This commit is contained in:
Martin van Wingerden 2021-01-25 22:56:08 +01:00 committed by GitHub
parent 781a824b79
commit 5dd30ea35f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 112 additions and 10 deletions

View File

@ -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<HeosMediaEventListener> heosMediaEventListeners = new CopyOnWriteArraySet<>();
private final List<HeosPlayerDiscoveryListener> 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<Class<? extends ThingHandlerService>> getServices() {
return Collections.singletonList(HeosActions.class);
}
public void registerMediaEventListener(HeosMediaEventListener heosMediaEventListener) {
heosMediaEventListeners.add(heosMediaEventListener);
}
}

View File

@ -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<String, Media> 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);
}
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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<HeosEventListener> listenerList = new CopyOnWriteArraySet<>();
private final Set<HeosEventListener> listenerList = new CopyOnWriteArraySet<>();
/**
* Register a listener from type {@link HeosEventListener} to be notified by