mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-02-04 11:24:10 +01:00
[sonos] Play notification while playing virtual line-in (#10599)
* Play notification while playing virtual line-in Fix #10569 Signed-off-by: Laurent Garnier <lg.hc@free.fr>
This commit is contained in:
parent
ffa17c76c1
commit
4efccacb10
@ -86,6 +86,7 @@ public class ZonePlayerHandler extends BaseThingHandler implements UpnpIOPartici
|
|||||||
|
|
||||||
private static final String ANALOG_LINE_IN_URI = "x-rincon-stream:";
|
private static final String ANALOG_LINE_IN_URI = "x-rincon-stream:";
|
||||||
private static final String OPTICAL_LINE_IN_URI = "x-sonos-htastream:";
|
private static final String OPTICAL_LINE_IN_URI = "x-sonos-htastream:";
|
||||||
|
private static final String VIRTUAL_LINE_IN_URI = "x-sonos-vli:";
|
||||||
private static final String QUEUE_URI = "x-rincon-queue:";
|
private static final String QUEUE_URI = "x-rincon-queue:";
|
||||||
private static final String GROUP_URI = "x-rincon:";
|
private static final String GROUP_URI = "x-rincon:";
|
||||||
private static final String STREAM_URI = "x-sonosapi-stream:";
|
private static final String STREAM_URI = "x-sonosapi-stream:";
|
||||||
@ -482,19 +483,19 @@ public class ZonePlayerHandler extends BaseThingHandler implements UpnpIOPartici
|
|||||||
this.stateMap.put(variable, value);
|
this.stateMap.put(variable, value);
|
||||||
|
|
||||||
// pre-process some variables, eg XML processing
|
// pre-process some variables, eg XML processing
|
||||||
if (service.equals(SERVICE_AV_TRANSPORT) && variable.equals("LastChange")) {
|
if (SERVICE_AV_TRANSPORT.equals(service) && "LastChange".equals(variable)) {
|
||||||
Map<String, String> parsedValues = SonosXMLParser.getAVTransportFromXML(value);
|
Map<String, String> parsedValues = SonosXMLParser.getAVTransportFromXML(value);
|
||||||
parsedValues.forEach((variable1, value1) -> {
|
parsedValues.forEach((variable1, value1) -> {
|
||||||
// Update the transport state after the update of the media information
|
// Update the transport state after the update of the media information
|
||||||
// to not break the notification mechanism
|
// to not break the notification mechanism
|
||||||
if (!variable1.equals("TransportState")) {
|
if (!"TransportState".equals(variable1)) {
|
||||||
onValueReceived(variable1, value1, service);
|
onValueReceived(variable1, value1, service);
|
||||||
}
|
}
|
||||||
// Translate AVTransportURI/AVTransportURIMetaData to CurrentURI/CurrentURIMetaData
|
// Translate AVTransportURI/AVTransportURIMetaData to CurrentURI/CurrentURIMetaData
|
||||||
// for a compatibility with the result of the action GetMediaInfo
|
// for a compatibility with the result of the action GetMediaInfo
|
||||||
if (variable1.equals("AVTransportURI")) {
|
if ("AVTransportURI".equals(variable1)) {
|
||||||
onValueReceived("CurrentURI", value1, service);
|
onValueReceived("CurrentURI", value1, service);
|
||||||
} else if (variable1.equals("AVTransportURIMetaData")) {
|
} else if ("AVTransportURIMetaData".equals(variable1)) {
|
||||||
onValueReceived("CurrentURIMetaData", value1, service);
|
onValueReceived("CurrentURIMetaData", value1, service);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -504,7 +505,7 @@ public class ZonePlayerHandler extends BaseThingHandler implements UpnpIOPartici
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (service.equals(SERVICE_RENDERING_CONTROL) && variable.equals("LastChange")) {
|
if (SERVICE_RENDERING_CONTROL.equals(service) && "LastChange".equals(variable)) {
|
||||||
Map<String, String> parsedValues = SonosXMLParser.getRenderingControlFromXML(value);
|
Map<String, String> parsedValues = SonosXMLParser.getRenderingControlFromXML(value);
|
||||||
parsedValues.forEach((variable1, value1) -> {
|
parsedValues.forEach((variable1, value1) -> {
|
||||||
onValueReceived(variable1, value1, service);
|
onValueReceived(variable1, value1, service);
|
||||||
@ -648,12 +649,12 @@ public class ZonePlayerHandler extends BaseThingHandler implements UpnpIOPartici
|
|||||||
updateChannel(CURRENTALBUMARTURL);
|
updateChannel(CURRENTALBUMARTURL);
|
||||||
break;
|
break;
|
||||||
case "CurrentSleepTimerGeneration":
|
case "CurrentSleepTimerGeneration":
|
||||||
if (value.equals("0")) {
|
if ("0".equals(value)) {
|
||||||
updateState(SLEEPTIMER, new DecimalType(0));
|
updateState(SLEEPTIMER, new DecimalType(0));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "SleepTimerGeneration":
|
case "SleepTimerGeneration":
|
||||||
if (value.equals("0")) {
|
if ("0".equals(value)) {
|
||||||
updateState(SLEEPTIMER, new DecimalType(0));
|
updateState(SLEEPTIMER, new DecimalType(0));
|
||||||
} else {
|
} else {
|
||||||
updateSleepTimerDuration();
|
updateSleepTimerDuration();
|
||||||
@ -1747,19 +1748,17 @@ public class ZonePlayerHandler extends BaseThingHandler implements UpnpIOPartici
|
|||||||
}
|
}
|
||||||
|
|
||||||
String transportState = state.transportState;
|
String transportState = state.transportState;
|
||||||
if (transportState != null) {
|
if (STATE_PLAYING.equals(transportState)) {
|
||||||
if (transportState.equals(STATE_PLAYING)) {
|
|
||||||
play();
|
play();
|
||||||
} else if (transportState.equals(STATE_STOPPED)) {
|
} else if (STATE_STOPPED.equals(transportState)) {
|
||||||
stop();
|
stop();
|
||||||
} else if (transportState.equals(STATE_PAUSED_PLAYBACK)) {
|
} else if (STATE_PAUSED_PLAYBACK.equals(transportState)) {
|
||||||
pause();
|
pause();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void saveQueue(String name, String queueID) {
|
public void saveQueue(String name, String queueID) {
|
||||||
executeAction(SERVICE_AV_TRANSPORT, ACTION_SAVE_QUEUE, Map.of("Title", name, "ObjectID", queueID));
|
executeAction(SERVICE_AV_TRANSPORT, ACTION_SAVE_QUEUE, Map.of("Title", name, "ObjectID", queueID));
|
||||||
@ -2583,13 +2582,17 @@ public class ZonePlayerHandler extends BaseThingHandler implements UpnpIOPartici
|
|||||||
|
|
||||||
if (isPlayingStream(currentURI) || isPlayingRadioStartedByAmazonEcho(currentURI)
|
if (isPlayingStream(currentURI) || isPlayingRadioStartedByAmazonEcho(currentURI)
|
||||||
|| isPlayingRadio(currentURI)) {
|
|| isPlayingRadio(currentURI)) {
|
||||||
handleRadioStream(currentURI, notificationURL, coordinator);
|
handleNotifForRadioStream(currentURI, notificationURL, coordinator);
|
||||||
} else if (isPlayingLineIn(currentURI)) {
|
} else if (isPlayingLineIn(currentURI)) {
|
||||||
handleLineIn(currentURI, notificationURL, coordinator);
|
handleNotifForLineIn(currentURI, notificationURL, coordinator);
|
||||||
|
} else if (isPlayingVirtualLineIn(currentURI)) {
|
||||||
|
handleNotifForVirtualLineIn(currentURI, notificationURL, coordinator);
|
||||||
} else if (isPlayingQueue(currentURI)) {
|
} else if (isPlayingQueue(currentURI)) {
|
||||||
handleSharedQueue(currentURI, notificationURL, coordinator);
|
handleNotifForSharedQueue(currentURI, notificationURL, coordinator);
|
||||||
} else if (isPlaylistEmpty(coordinator)) {
|
} else if (isPlaylistEmpty(coordinator)) {
|
||||||
handleEmptyQueue(notificationURL, coordinator);
|
handleNotifForEmptyQueue(notificationURL, coordinator);
|
||||||
|
} else {
|
||||||
|
logger.debug("Notification feature not yet implemented while the current media is being played");
|
||||||
}
|
}
|
||||||
synchronized (notificationLock) {
|
synchronized (notificationLock) {
|
||||||
notificationLock.notify();
|
notificationLock.notify();
|
||||||
@ -2635,6 +2638,10 @@ public class ZonePlayerHandler extends BaseThingHandler implements UpnpIOPartici
|
|||||||
return currentURI != null && currentURI.startsWith(OPTICAL_LINE_IN_URI) && currentURI.endsWith(SPDIF);
|
return currentURI != null && currentURI.startsWith(OPTICAL_LINE_IN_URI) && currentURI.endsWith(SPDIF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isPlayingVirtualLineIn(@Nullable String currentURI) {
|
||||||
|
return currentURI != null && currentURI.startsWith(VIRTUAL_LINE_IN_URI);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does a chain of predefined actions when a Notification sound is played by
|
* Does a chain of predefined actions when a Notification sound is played by
|
||||||
* {@link ZonePlayerHandler#playNotificationSoundURI(Command)} in case
|
* {@link ZonePlayerHandler#playNotificationSoundURI(Command)} in case
|
||||||
@ -2645,7 +2652,7 @@ public class ZonePlayerHandler extends BaseThingHandler implements UpnpIOPartici
|
|||||||
* @param coordinator - {@link ZonePlayerHandler} coordinator for the SONOS device(s)
|
* @param coordinator - {@link ZonePlayerHandler} coordinator for the SONOS device(s)
|
||||||
* @throws InterruptedException
|
* @throws InterruptedException
|
||||||
*/
|
*/
|
||||||
private void handleRadioStream(@Nullable String currentStreamURI, Command notificationURL,
|
private void handleNotifForRadioStream(@Nullable String currentStreamURI, Command notificationURL,
|
||||||
ZonePlayerHandler coordinator) throws InterruptedException {
|
ZonePlayerHandler coordinator) throws InterruptedException {
|
||||||
String nextAction = coordinator.getTransportState();
|
String nextAction = coordinator.getTransportState();
|
||||||
SonosMetaData track = coordinator.getTrackMetadata();
|
SonosMetaData track = coordinator.getTrackMetadata();
|
||||||
@ -2669,19 +2676,44 @@ public class ZonePlayerHandler extends BaseThingHandler implements UpnpIOPartici
|
|||||||
* @param coordinator - {@link ZonePlayerHandler} coordinator for the SONOS device(s)
|
* @param coordinator - {@link ZonePlayerHandler} coordinator for the SONOS device(s)
|
||||||
* @throws InterruptedException
|
* @throws InterruptedException
|
||||||
*/
|
*/
|
||||||
private void handleLineIn(@Nullable String currentLineInURI, Command notificationURL, ZonePlayerHandler coordinator)
|
private void handleNotifForLineIn(@Nullable String currentLineInURI, Command notificationURL,
|
||||||
throws InterruptedException {
|
ZonePlayerHandler coordinator) throws InterruptedException {
|
||||||
logger.debug("Handling notification while sound from line-in was being played");
|
logger.debug("Handling notification while sound from line-in was being played");
|
||||||
String nextAction = coordinator.getTransportState();
|
String nextAction = coordinator.getTransportState();
|
||||||
|
|
||||||
handleNotificationSound(notificationURL, coordinator);
|
handleNotificationSound(notificationURL, coordinator);
|
||||||
if (currentLineInURI != null) {
|
if (currentLineInURI != null) {
|
||||||
logger.debug("Restoring sound from line-in using {}", currentLineInURI);
|
logger.debug("Restoring sound from line-in using URI {}", currentLineInURI);
|
||||||
coordinator.setCurrentURI(currentLineInURI, "");
|
coordinator.setCurrentURI(currentLineInURI, "");
|
||||||
restoreLastTransportState(coordinator, nextAction);
|
restoreLastTransportState(coordinator, nextAction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does a chain of predefined actions when a Notification sound is played by
|
||||||
|
* {@link ZonePlayerHandler#playNotificationSoundURI(Command)} in case
|
||||||
|
* virtual line in is currently loaded
|
||||||
|
*
|
||||||
|
* @param currentVirtualLineInURI - the currently loaded virtual line-in URI
|
||||||
|
* @param notificationURL - the notification url in the format of //host/folder/filename.mp3
|
||||||
|
* @param coordinator - {@link ZonePlayerHandler} coordinator for the SONOS device(s)
|
||||||
|
* @throws InterruptedException
|
||||||
|
*/
|
||||||
|
private void handleNotifForVirtualLineIn(@Nullable String currentVirtualLineInURI, Command notificationURL,
|
||||||
|
ZonePlayerHandler coordinator) throws InterruptedException {
|
||||||
|
logger.debug("Handling notification while sound from virtual line-in was being played");
|
||||||
|
String nextAction = coordinator.getTransportState();
|
||||||
|
String currentUriMetaData = coordinator.getCurrentURIMetadataAsString();
|
||||||
|
|
||||||
|
handleNotificationSound(notificationURL, coordinator);
|
||||||
|
if (currentVirtualLineInURI != null && currentUriMetaData != null) {
|
||||||
|
logger.debug("Restoring sound from virtual line-in using URI {} and metadata {}", currentVirtualLineInURI,
|
||||||
|
currentUriMetaData);
|
||||||
|
coordinator.setCurrentURI(currentVirtualLineInURI, currentUriMetaData);
|
||||||
|
restoreLastTransportState(coordinator, nextAction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does a chain of predefined actions when a Notification sound is played by
|
* Does a chain of predefined actions when a Notification sound is played by
|
||||||
* {@link ZonePlayerHandler#playNotificationSoundURI(Command)} in case
|
* {@link ZonePlayerHandler#playNotificationSoundURI(Command)} in case
|
||||||
@ -2692,13 +2724,14 @@ public class ZonePlayerHandler extends BaseThingHandler implements UpnpIOPartici
|
|||||||
* @param coordinator - {@link ZonePlayerHandler} coordinator for the SONOS device(s)
|
* @param coordinator - {@link ZonePlayerHandler} coordinator for the SONOS device(s)
|
||||||
* @throws InterruptedException
|
* @throws InterruptedException
|
||||||
*/
|
*/
|
||||||
private void handleSharedQueue(@Nullable String currentQueueURI, Command notificationURL,
|
private void handleNotifForSharedQueue(@Nullable String currentQueueURI, Command notificationURL,
|
||||||
ZonePlayerHandler coordinator) throws InterruptedException {
|
ZonePlayerHandler coordinator) throws InterruptedException {
|
||||||
String nextAction = coordinator.getTransportState();
|
String nextAction = coordinator.getTransportState();
|
||||||
String trackPosition = coordinator.getRefreshedPosition();
|
String trackPosition = coordinator.getRefreshedPosition();
|
||||||
long currentTrackNumber = coordinator.getRefreshedCurrenTrackNr();
|
long currentTrackNumber = coordinator.getRefreshedCurrenTrackNr();
|
||||||
logger.debug("handleSharedQueue: currentQueueURI {} trackPosition {} currentTrackNumber {}", currentQueueURI,
|
logger.debug(
|
||||||
trackPosition, currentTrackNumber);
|
"Handling notification while playing queue: currentQueueURI {} trackPosition {} currentTrackNumber {}",
|
||||||
|
currentQueueURI, trackPosition, currentTrackNumber);
|
||||||
|
|
||||||
handleNotificationSound(notificationURL, coordinator);
|
handleNotificationSound(notificationURL, coordinator);
|
||||||
String queueUri = QUEUE_URI + coordinator.getUDN() + "#0";
|
String queueUri = QUEUE_URI + coordinator.getUDN() + "#0";
|
||||||
@ -2766,7 +2799,8 @@ public class ZonePlayerHandler extends BaseThingHandler implements UpnpIOPartici
|
|||||||
* @param coordinator - {@link ZonePlayerHandler} coordinator for the SONOS device(s)
|
* @param coordinator - {@link ZonePlayerHandler} coordinator for the SONOS device(s)
|
||||||
* @throws InterruptedException
|
* @throws InterruptedException
|
||||||
*/
|
*/
|
||||||
private void handleEmptyQueue(Command notificationURL, ZonePlayerHandler coordinator) throws InterruptedException {
|
private void handleNotifForEmptyQueue(Command notificationURL, ZonePlayerHandler coordinator)
|
||||||
|
throws InterruptedException {
|
||||||
String originalVolume = coordinator.getVolume();
|
String originalVolume = coordinator.getVolume();
|
||||||
coordinator.applyNotificationSoundVolume();
|
coordinator.applyNotificationSoundVolume();
|
||||||
coordinator.playURI(notificationURL);
|
coordinator.playURI(notificationURL);
|
||||||
@ -2951,7 +2985,7 @@ public class ZonePlayerHandler extends BaseThingHandler implements UpnpIOPartici
|
|||||||
// search for the TuneIn music service based on its name
|
// search for the TuneIn music service based on its name
|
||||||
if (allServices != null) {
|
if (allServices != null) {
|
||||||
for (SonosMusicService service : allServices) {
|
for (SonosMusicService service : allServices) {
|
||||||
if (service.getName().equals("TuneIn")) {
|
if ("TuneIn".equals(service.getName())) {
|
||||||
tuneinService = service;
|
tuneinService = service;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2999,7 +3033,7 @@ public class ZonePlayerHandler extends BaseThingHandler implements UpnpIOPartici
|
|||||||
|
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
for (SonosMusicService service : services) {
|
for (SonosMusicService service : services) {
|
||||||
if (!service.getName().equals("TuneIn")) {
|
if (!"TuneIn".equals(service.getName())) {
|
||||||
// Add the service type integer value from "AvailableServiceTypeList" to each service
|
// Add the service type integer value from "AvailableServiceTypeList" to each service
|
||||||
// except TuneIn
|
// except TuneIn
|
||||||
if (idx < servicesTypes.length) {
|
if (idx < servicesTypes.length) {
|
||||||
|
Loading…
Reference in New Issue
Block a user