From 3f1e9713b2d84954697f8b40cafe4c511da884e9 Mon Sep 17 00:00:00 2001 From: Laurent Garnier Date: Tue, 27 Apr 2021 19:03:56 +0200 Subject: [PATCH 1/3] [sonos] Play notification while playing virtual line-in Fix #10569 Signed-off-by: Laurent Garnier --- .../internal/handler/ZonePlayerHandler.java | 66 ++++++++++++++----- 1 file changed, 48 insertions(+), 18 deletions(-) diff --git a/bundles/org.openhab.binding.sonos/src/main/java/org/openhab/binding/sonos/internal/handler/ZonePlayerHandler.java b/bundles/org.openhab.binding.sonos/src/main/java/org/openhab/binding/sonos/internal/handler/ZonePlayerHandler.java index aca3820ce1aea..9c211383fe9ba 100644 --- a/bundles/org.openhab.binding.sonos/src/main/java/org/openhab/binding/sonos/internal/handler/ZonePlayerHandler.java +++ b/bundles/org.openhab.binding.sonos/src/main/java/org/openhab/binding/sonos/internal/handler/ZonePlayerHandler.java @@ -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 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 GROUP_URI = "x-rincon:"; private static final String STREAM_URI = "x-sonosapi-stream:"; @@ -482,19 +483,19 @@ public void onValueReceived(@Nullable String variable, @Nullable String value, @ this.stateMap.put(variable, value); // 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 parsedValues = SonosXMLParser.getAVTransportFromXML(value); parsedValues.forEach((variable1, value1) -> { // Update the transport state after the update of the media information // to not break the notification mechanism - if (!variable1.equals("TransportState")) { + if (!"TransportState".equals(variable1)) { onValueReceived(variable1, value1, service); } // Translate AVTransportURI/AVTransportURIMetaData to CurrentURI/CurrentURIMetaData // for a compatibility with the result of the action GetMediaInfo - if (variable1.equals("AVTransportURI")) { + if ("AVTransportURI".equals(variable1)) { onValueReceived("CurrentURI", value1, service); - } else if (variable1.equals("AVTransportURIMetaData")) { + } else if ("AVTransportURIMetaData".equals(variable1)) { onValueReceived("CurrentURIMetaData", value1, service); } }); @@ -504,7 +505,7 @@ public void onValueReceived(@Nullable String variable, @Nullable String value, @ } } - if (service.equals(SERVICE_RENDERING_CONTROL) && variable.equals("LastChange")) { + if (SERVICE_RENDERING_CONTROL.equals(service) && "LastChange".equals(variable)) { Map parsedValues = SonosXMLParser.getRenderingControlFromXML(value); parsedValues.forEach((variable1, value1) -> { onValueReceived(variable1, value1, service); @@ -648,12 +649,12 @@ public void onValueReceived(@Nullable String variable, @Nullable String value, @ updateChannel(CURRENTALBUMARTURL); break; case "CurrentSleepTimerGeneration": - if (value.equals("0")) { + if ("0".equals(value)) { updateState(SLEEPTIMER, new DecimalType(0)); } break; case "SleepTimerGeneration": - if (value.equals("0")) { + if ("0".equals(value)) { updateState(SLEEPTIMER, new DecimalType(0)); } else { updateSleepTimerDuration(); @@ -1747,14 +1748,12 @@ protected void restoreState() { } String transportState = state.transportState; - if (transportState != null) { - if (transportState.equals(STATE_PLAYING)) { - play(); - } else if (transportState.equals(STATE_STOPPED)) { - stop(); - } else if (transportState.equals(STATE_PAUSED_PLAYBACK)) { - pause(); - } + if (STATE_PLAYING.equals(transportState)) { + play(); + } else if (STATE_STOPPED.equals(transportState)) { + stop(); + } else if (STATE_PAUSED_PLAYBACK.equals(transportState)) { + pause(); } } } @@ -2586,6 +2585,8 @@ public void playNotificationSoundURI(Command notificationURL) { handleRadioStream(currentURI, notificationURL, coordinator); } else if (isPlayingLineIn(currentURI)) { handleLineIn(currentURI, notificationURL, coordinator); + } else if (isPlayingVirtualLineIn(currentURI)) { + handleVirtualLineIn(currentURI, notificationURL, coordinator); } else if (isPlayingQueue(currentURI)) { handleSharedQueue(currentURI, notificationURL, coordinator); } else if (isPlaylistEmpty(coordinator)) { @@ -2635,6 +2636,10 @@ private boolean isPlayingOpticalLineIn(@Nullable String currentURI) { 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 * {@link ZonePlayerHandler#playNotificationSoundURI(Command)} in case @@ -2676,12 +2681,37 @@ private void handleLineIn(@Nullable String currentLineInURI, Command notificatio handleNotificationSound(notificationURL, coordinator); 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, ""); 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 handleVirtualLineIn(@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 * {@link ZonePlayerHandler#playNotificationSoundURI(Command)} in case @@ -2951,7 +2981,7 @@ public void playTuneinStation(Command command) { // search for the TuneIn music service based on its name if (allServices != null) { for (SonosMusicService service : allServices) { - if (service.getName().equals("TuneIn")) { + if ("TuneIn".equals(service.getName())) { tuneinService = service; break; } @@ -2999,7 +3029,7 @@ public void playTuneinStation(Command command) { int idx = 0; 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 // except TuneIn if (idx < servicesTypes.length) { From 16f0b3fdf8c01bb128313b112d94d57cb157a2d3 Mon Sep 17 00:00:00 2001 From: Laurent Garnier Date: Wed, 28 Apr 2021 09:25:28 +0200 Subject: [PATCH 2/3] Add a log in case the notification feature is not yet implemented Signed-off-by: Laurent Garnier --- .../binding/sonos/internal/handler/ZonePlayerHandler.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bundles/org.openhab.binding.sonos/src/main/java/org/openhab/binding/sonos/internal/handler/ZonePlayerHandler.java b/bundles/org.openhab.binding.sonos/src/main/java/org/openhab/binding/sonos/internal/handler/ZonePlayerHandler.java index 9c211383fe9ba..5b6d823e7c1b7 100644 --- a/bundles/org.openhab.binding.sonos/src/main/java/org/openhab/binding/sonos/internal/handler/ZonePlayerHandler.java +++ b/bundles/org.openhab.binding.sonos/src/main/java/org/openhab/binding/sonos/internal/handler/ZonePlayerHandler.java @@ -2591,6 +2591,8 @@ public void playNotificationSoundURI(Command notificationURL) { handleSharedQueue(currentURI, notificationURL, coordinator); } else if (isPlaylistEmpty(coordinator)) { handleEmptyQueue(notificationURL, coordinator); + } else { + logger.debug("Notification feature not yet implemented while the current media is being played"); } synchronized (notificationLock) { notificationLock.notify(); From 34b8ed24c9b344bf0915047aca4faa511887fc27 Mon Sep 17 00:00:00 2001 From: Laurent Garnier Date: Wed, 28 Apr 2021 11:27:36 +0200 Subject: [PATCH 3/3] Rename few methods for better meaning Signed-off-by: Laurent Garnier --- .../internal/handler/ZonePlayerHandler.java | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/bundles/org.openhab.binding.sonos/src/main/java/org/openhab/binding/sonos/internal/handler/ZonePlayerHandler.java b/bundles/org.openhab.binding.sonos/src/main/java/org/openhab/binding/sonos/internal/handler/ZonePlayerHandler.java index 5b6d823e7c1b7..e0043c2085cb0 100644 --- a/bundles/org.openhab.binding.sonos/src/main/java/org/openhab/binding/sonos/internal/handler/ZonePlayerHandler.java +++ b/bundles/org.openhab.binding.sonos/src/main/java/org/openhab/binding/sonos/internal/handler/ZonePlayerHandler.java @@ -2582,15 +2582,15 @@ public void playNotificationSoundURI(Command notificationURL) { if (isPlayingStream(currentURI) || isPlayingRadioStartedByAmazonEcho(currentURI) || isPlayingRadio(currentURI)) { - handleRadioStream(currentURI, notificationURL, coordinator); + handleNotifForRadioStream(currentURI, notificationURL, coordinator); } else if (isPlayingLineIn(currentURI)) { - handleLineIn(currentURI, notificationURL, coordinator); + handleNotifForLineIn(currentURI, notificationURL, coordinator); } else if (isPlayingVirtualLineIn(currentURI)) { - handleVirtualLineIn(currentURI, notificationURL, coordinator); + handleNotifForVirtualLineIn(currentURI, notificationURL, coordinator); } else if (isPlayingQueue(currentURI)) { - handleSharedQueue(currentURI, notificationURL, coordinator); + handleNotifForSharedQueue(currentURI, notificationURL, 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"); } @@ -2652,7 +2652,7 @@ private boolean isPlayingVirtualLineIn(@Nullable String currentURI) { * @param coordinator - {@link ZonePlayerHandler} coordinator for the SONOS device(s) * @throws InterruptedException */ - private void handleRadioStream(@Nullable String currentStreamURI, Command notificationURL, + private void handleNotifForRadioStream(@Nullable String currentStreamURI, Command notificationURL, ZonePlayerHandler coordinator) throws InterruptedException { String nextAction = coordinator.getTransportState(); SonosMetaData track = coordinator.getTrackMetadata(); @@ -2676,8 +2676,8 @@ private void handleRadioStream(@Nullable String currentStreamURI, Command notifi * @param coordinator - {@link ZonePlayerHandler} coordinator for the SONOS device(s) * @throws InterruptedException */ - private void handleLineIn(@Nullable String currentLineInURI, Command notificationURL, ZonePlayerHandler coordinator) - throws InterruptedException { + private void handleNotifForLineIn(@Nullable String currentLineInURI, Command notificationURL, + ZonePlayerHandler coordinator) throws InterruptedException { logger.debug("Handling notification while sound from line-in was being played"); String nextAction = coordinator.getTransportState(); @@ -2699,7 +2699,7 @@ private void handleLineIn(@Nullable String currentLineInURI, Command notificatio * @param coordinator - {@link ZonePlayerHandler} coordinator for the SONOS device(s) * @throws InterruptedException */ - private void handleVirtualLineIn(@Nullable String currentVirtualLineInURI, Command notificationURL, + 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(); @@ -2724,13 +2724,14 @@ private void handleVirtualLineIn(@Nullable String currentVirtualLineInURI, Comma * @param coordinator - {@link ZonePlayerHandler} coordinator for the SONOS device(s) * @throws InterruptedException */ - private void handleSharedQueue(@Nullable String currentQueueURI, Command notificationURL, + private void handleNotifForSharedQueue(@Nullable String currentQueueURI, Command notificationURL, ZonePlayerHandler coordinator) throws InterruptedException { String nextAction = coordinator.getTransportState(); String trackPosition = coordinator.getRefreshedPosition(); long currentTrackNumber = coordinator.getRefreshedCurrenTrackNr(); - logger.debug("handleSharedQueue: currentQueueURI {} trackPosition {} currentTrackNumber {}", currentQueueURI, - trackPosition, currentTrackNumber); + logger.debug( + "Handling notification while playing queue: currentQueueURI {} trackPosition {} currentTrackNumber {}", + currentQueueURI, trackPosition, currentTrackNumber); handleNotificationSound(notificationURL, coordinator); String queueUri = QUEUE_URI + coordinator.getUDN() + "#0"; @@ -2798,7 +2799,8 @@ private void restoreLastTransportState(ZonePlayerHandler coordinator, @Nullable * @param coordinator - {@link ZonePlayerHandler} coordinator for the SONOS device(s) * @throws InterruptedException */ - private void handleEmptyQueue(Command notificationURL, ZonePlayerHandler coordinator) throws InterruptedException { + private void handleNotifForEmptyQueue(Command notificationURL, ZonePlayerHandler coordinator) + throws InterruptedException { String originalVolume = coordinator.getVolume(); coordinator.applyNotificationSoundVolume(); coordinator.playURI(notificationURL);