]> git.basschouten.com Git - openhab-addons.git/commitdiff
[chromecast] Fix thing go offline after stop command (#14158)
authorlsiepel <leosiepel@gmail.com>
Sat, 7 Jan 2023 08:51:20 +0000 (09:51 +0100)
committerGitHub <noreply@github.com>
Sat, 7 Jan 2023 08:51:20 +0000 (09:51 +0100)
* Restructure commander
* Improve thing status handling on error

Signed-off-by: lsiepel <leosiepel@gmail.com>
bundles/org.openhab.binding.chromecast/src/main/java/org/openhab/binding/chromecast/internal/ChromecastAudioSink.java
bundles/org.openhab.binding.chromecast/src/main/java/org/openhab/binding/chromecast/internal/ChromecastCommander.java
bundles/org.openhab.binding.chromecast/src/main/java/org/openhab/binding/chromecast/internal/ChromecastEventReceiver.java

index 199f982426515a1d27affe31af353674eb928516..4319fa421d2535f13087a62c378a8d44c7a6a7db 100644 (file)
@@ -52,7 +52,7 @@ public class ChromecastAudioSink {
             // in case the audioStream is null, this should be interpreted as a request to end any currently playing
             // stream.
             logger.trace("Stop currently playing stream.");
-            commander.handleStop(OnOffType.ON);
+            commander.handleCloseApp(OnOffType.ON);
         } else {
             final String url;
             if (audioStream instanceof URLAudioStream) {
index 0d83f960493011c5667f71ab71bc1966000d963f..a3d5206079721145cec5373c7e3b63bd9fed8e41 100644 (file)
@@ -70,7 +70,7 @@ public class ChromecastCommander {
                 handleControl(command);
                 break;
             case CHANNEL_STOP:
-                handleStop(command);
+                handleCloseApp(command);
                 break;
             case CHANNEL_VOLUME:
                 handleVolume(command);
@@ -117,7 +117,7 @@ public class ChromecastCommander {
                 if (mediaStatus != null && mediaStatus.playerState == MediaStatus.PlayerState.IDLE
                         && mediaStatus.idleReason != null
                         && mediaStatus.idleReason != MediaStatus.IdleReason.INTERRUPTED) {
-                    stopMediaPlayerApp();
+                    closeApp(MEDIA_PLAYER);
                 }
             }
         } catch (IOException ex) {
@@ -126,6 +126,12 @@ public class ChromecastCommander {
         }
     }
 
+    public void handleCloseApp(final Command command) {
+        if (command == OnOffType.ON) {
+            closeApp(MEDIA_PLAYER);
+        }
+    }
+
     private void handlePlayUri(Command command) {
         if (command instanceof StringType) {
             playMedia(null, command.toString(), null);
@@ -163,7 +169,6 @@ public class ChromecastCommander {
             if (command instanceof NextPreviousType) {
                 // Next is implemented by seeking to the end of the current media
                 if (command == NextPreviousType.NEXT) {
-
                     Double duration = statusUpdater.getLastDuration();
                     if (duration != null) {
                         chromeCast.seek(duration.doubleValue() - 5);
@@ -182,18 +187,6 @@ public class ChromecastCommander {
         }
     }
 
-    public void handleStop(final Command command) {
-        if (command == OnOffType.ON) {
-            try {
-                chromeCast.stopApp();
-                statusUpdater.updateStatus(ThingStatus.ONLINE);
-            } catch (final IOException ex) {
-                logger.debug("{} command failed: {}", command, ex.getMessage());
-                statusUpdater.updateStatus(ThingStatus.OFFLINE, COMMUNICATION_ERROR, ex.getMessage());
-            }
-        }
-    }
-
     public void handleVolume(final Command command) {
         if (command instanceof PercentType) {
             setVolumeInternal((PercentType) command);
@@ -229,44 +222,69 @@ public class ChromecastCommander {
         }
     }
 
-    public void playMedia(@Nullable String title, @Nullable String url, @Nullable String mimeType) {
+    public void startApp(@Nullable String appId) {
+        if (appId == null) {
+            return;
+        }
         try {
-            if (chromeCast.isAppAvailable(MEDIA_PLAYER)) {
-                if (!chromeCast.isAppRunning(MEDIA_PLAYER)) {
-                    final Application app = chromeCast.launchApp(MEDIA_PLAYER);
+            if (chromeCast.isAppAvailable(appId)) {
+                if (!chromeCast.isAppRunning(appId)) {
+                    final Application app = chromeCast.launchApp(appId);
                     statusUpdater.setAppSessionId(app.sessionId);
-                    logger.debug("Application launched: {}", app);
-                }
-                if (url != null) {
-                    // If the current track is paused, launching a new request results in nothing happening, therefore
-                    // resume current track.
-                    MediaStatus ms = chromeCast.getMediaStatus();
-                    if (ms != null && MediaStatus.PlayerState.PAUSED == ms.playerState && url.equals(ms.media.url)) {
-                        logger.debug("Current stream paused, resuming");
-                        chromeCast.play();
-                    } else {
-                        chromeCast.load(title, null, url, mimeType);
-                    }
+                    logger.debug("Application launched: {}", appId);
                 }
             } else {
-                logger.warn("Missing media player app - cannot process media.");
+                logger.warn("Failed starting app, app probably not installed. Appid: {}", appId);
             }
             statusUpdater.updateStatus(ThingStatus.ONLINE);
         } catch (final IOException e) {
-            logger.debug("Failed playing media: {}", e.getMessage());
-            statusUpdater.updateStatus(ThingStatus.OFFLINE, COMMUNICATION_ERROR, e.getMessage());
+            logger.warn("Failed starting app: {}. Message: {}", appId, e.getMessage());
         }
     }
 
-    private void stopMediaPlayerApp() {
+    public void closeApp(@Nullable String appId) {
+        if (appId == null) {
+            return;
+        }
+
         try {
-            Application app = chromeCast.getRunningApp();
-            if (app.id.equals(MEDIA_PLAYER) && app.sessionId.equals(statusUpdater.getAppSessionId())) {
-                chromeCast.stopApp();
-                logger.debug("Media player app stopped");
+            if (chromeCast.isAppRunning(appId)) {
+                Application app = chromeCast.getRunningApp();
+                if (app.id.equals(appId) && app.sessionId.equals(statusUpdater.getAppSessionId())) {
+                    chromeCast.stopApp();
+                    logger.debug("Application closed: {}", appId);
+                }
             }
         } catch (final IOException e) {
-            logger.debug("Failed stopping media player app", e);
+            logger.debug("Failed stopping media player app: {} with message: {}", appId, e.getMessage());
+        }
+    }
+
+    public void playMedia(@Nullable String title, @Nullable String url, @Nullable String mimeType) {
+        startApp(MEDIA_PLAYER);
+        try {
+            if (url != null && chromeCast.isAppRunning(MEDIA_PLAYER)) {
+                // If the current track is paused, launching a new request results in nothing happening, therefore
+                // resume current track.
+                MediaStatus ms = chromeCast.getMediaStatus();
+                if (ms != null && MediaStatus.PlayerState.PAUSED == ms.playerState && url.equals(ms.media.url)) {
+                    logger.debug("Current stream paused, resuming");
+                    chromeCast.play();
+                } else {
+                    chromeCast.load(title, null, url, mimeType);
+                }
+            } else {
+                logger.warn("Missing media player app - cannot process media.");
+            }
+            statusUpdater.updateStatus(ThingStatus.ONLINE);
+        } catch (final IOException e) {
+            if ("Unable to load media".equals(e.getMessage())) {
+                logger.warn("Unable to load media: {}", url);
+            } else {
+                logger.debug("Failed playing media: {}", e.getMessage());
+                statusUpdater.updateStatus(ThingStatus.OFFLINE, COMMUNICATION_ERROR,
+                        "IOException while trying to play media: " + e.getMessage());
+            }
         }
     }
 }
index f7fc578853af22bbc94937b6304d86394f7e8edd..2906bf32603ef0908d21be08b5dba0c585c0363c 100644 (file)
@@ -56,6 +56,8 @@ public class ChromecastEventReceiver implements ChromeCastSpontaneousEventListen
 
     @Override
     public void spontaneousEventReceived(final @NonNullByDefault({}) ChromeCastSpontaneousEvent event) {
+        logger.trace("Received an {} event (class={})", event.getType(), event.getData());
+
         switch (event.getType()) {
             case CLOSE:
                 statusUpdater.updateMediaStatus(null);
@@ -66,6 +68,9 @@ public class ChromecastEventReceiver implements ChromeCastSpontaneousEventListen
             case STATUS:
                 statusUpdater.processStatusUpdate(event.getData(Status.class));
                 break;
+            case APPEVENT:
+                logger.debug("Received an 'APPEVENT' event, ignoring");
+                break;
             case UNKNOWN:
                 logger.debug("Received an 'UNKNOWN' event (class={})", event.getType().getDataClass());
                 break;