Chromecast Binding - How to send STOPMOVETYPE


(Chris Colden) #1

Hi,

Been looking for a way to stop the chromecasts and exit the app thats running. When reviewing the code for the binding I see that the control handler accepts a STOPMOVETYPE which calls the required method in the chromecast api to exit the app on the device.

My issue is, that the Control channel excepts a player item and the player item doesn’t take a stopmovetype so I have no idea how it is possible to send a STOP command.

Below i have extracted the relevant code from the ChromecastCommander.java

    public void handleCommand(final ChannelUID channelUID, final Command command) {
        if (chromeCast == null) {
            return;
        }

        if (command instanceof RefreshType) {
            handleRefresh();
            return;
        }

        switch (channelUID.getId()) {
            case CHANNEL_CONTROL:
                handleControl(command);
                break;
            case CHANNEL_VOLUME:
                handleVolume(command);
                break;
            case CHANNEL_MUTE:
                handleMute(command);
                break;
            case CHANNEL_PLAY_URI:
                handlePlayUri(command);
                break;
            default:
                logger.debug("Received command {} for unknown channel: {}", command, channelUID);
                break;
        }
    }
private void handleControl(final Command command) {
        try {
            if (command instanceof NextPreviousType) {
                // I can't find a way to control next/previous from the API. The Google app doesn't seem to
                // allow it either, so I suspect there isn't a way.
                logger.info("{} command not yet implemented", command);
                return;
            }

            Application app = chromeCast.getRunningApp();
            statusUpdater.updateStatus(ThingStatus.ONLINE);
            if (app == null) {
                logger.debug("{} command ignored because media player app is not running", command);
                return;
            }

            if (command instanceof StopMoveType) {
                final StopMoveType stopMoveType = (StopMoveType) command;
                if (stopMoveType == StopMoveType.STOP) {
                    chromeCast.stopApp();
                    statusUpdater.updateMediaStatus(null);
                }
                return;
            }

            if (command instanceof PlayPauseType) {
                MediaStatus mediaStatus = chromeCast.getMediaStatus();
                logger.debug("mediaStatus {}", mediaStatus);
                if (mediaStatus == null || mediaStatus.playerState == MediaStatus.PlayerState.IDLE) {
                    logger.debug("{} command ignored because media is not loaded", command);
                    return;
                }

                final PlayPauseType playPause = (PlayPauseType) command;
                if (playPause == PlayPauseType.PLAY) {
                    chromeCast.play();
                } else if (playPause == PlayPauseType.PAUSE
                        && ((mediaStatus.supportedMediaCommands & 0x00000001) == 0x1)) {
                    chromeCast.pause();
                } else {
                    logger.info("{} command not supported by current media", command);
                }
            }
        } catch (final Exception e) {
            logger.debug("{} command failed: {}", command, e.getMessage());
            statusUpdater.updateStatus(ThingStatus.OFFLINE, COMMUNICATION_ERROR, e.getMessage());
        }
    }

Just trying to work out if this should be logs as an issue with the binding, or if i’m just being dumb.

Thanks
Chris


(Christoph Weitkamp) #2

Hi Chris,

The only Item I am aware of which accepts a StopMoveType is a Rollershutter item. From my point of view it does not make sense to link it to the control channel. Furthermore I think the current implementation should be removed from the binding. Rather implement a dedicated stop channel of item type Switch which is the way how we did it in other media control bindings (e.g. Kodi).

You can try to link a String item and either send a “STOP” command via rule or implement a Switch element using a mapping in a sitemap. But I am afraid they will not be recognized as StopMoveType.


(Chris Colden) #3

So were saying this code in the binding has been implemented incorrectly? If so I will create an issue for it.


(Christoph Weitkamp) #4

I would vote for: Yes.


(Christoph Weitkamp) #5

I removed the implementation of StopMoveType from control channel and added a dedicated stop channel for all things. If you are interested in testing you will find a test version here:


[SOLVED] How do I stop the chromecast's stream?
(Chris Colden) #6

Great work. I will try this tomorrow and let you know how it goes.

thank you.

Chris


(Chris Colden) #7

Having trouble installing this.

I am on milestone build 2.5.0 M1. I’ve uninstalled the normal binding from paperui, stopped openhab, cleaned the cache, and started and has installed the binding from the openhab2-addons package instead of yours via addons.cfg.

Any ideas where I’m going wrong?

Thanks
Chris


(Christoph Weitkamp) #8

Is the Chromecast binding listed in the binding section of your addons.cfg file? If so remove it and restart again.


(Chris Colden) #9

It was, ive tried removing it from addons, uninstalling. stoppping openhab, cleaning cache, starting, installing from paperui, but i still dont have the stop channel, so its still installing from the addons package.


(Chris Colden) #10

Installing from console gives me the following…

openhab> bundle:install org.openhab.binding.chromecast
Bundle IDs:
Error executing command: Error installing bundles:
        Unable to install bundle org.openhab.binding.chromecast: org.osgi.framework.BundleException: Error reading bundle content.

(Christoph Weitkamp) #11

Did you install the openhab2-addons package in a Linux environment? If so please uninstall it and try again.


(Chris Colden) #12

I’ve done that but no difference.

So i thought id manually go and configure a thing and the extra channel showed up. So i’m running your test binding, but looks like i’ll have to go and remove and re-add each of the things.

Chris


(Christoph Weitkamp) #13

Ah, damn, I am always missing the easy part. Yes, you have to re-add all your things.

While testing can you please observe it the status or the control channel (the Player Item) will be updated accordingly? If so we can close additional issue. Thank you very much.


(Chris Colden) #14

Sure, when you say the status do you mean the status of the thing? As I was having issues with Groups not getting the new owners ip when they decide to move about.


(Christoph Weitkamp) #15

I have to correct my post. Too much spelling mistakes.

Can you please observe if the state of then control channel will be updated accordingly.


(Chris Colden) #16

Sure will do.

Stop channel seems to be working as expected. Thank you.
The only thing i’ve noticed so far is the discovery of things. Audio or audio group things doesn’t discover when there is another thing listed under the same ip.

The way the groups work is they are virtual on the audio. So the same ip will be listed multiple times under different things. I could have 1 audio and 3 groups all with the same ip. Although my audios ip’s are fixed by dhcp, unfortunately sometimes the master moves and the ip needs to be updated.

Currently this doesn’t automatically update either. I have to go in and find the ip which is now hosting the virtual group.

I think the issue is related to the ip, as i removed and audio thing, and it wouldn’t discover it. Once i removed the offending group, it pinged into the inbox. I think the logic is slightly wrong in the binding here.

Thanks again
Chris


(Chris Colden) #17

As far as the control channel. Moving between play and pause is working as expected at the moment. Tested with spotify. Next / previous dont work, but thats as expected too.

Other than the above, which was a pre-existing issue its working great.


(Christoph Weitkamp) #18

Thank you too for testing. I saw your issue on GitHub wrt to changing audiogroup masters. Unfortunately I am not able to test or reproduce it because I do not have access to multiple devices.

But I think we can work on the discovery stuff. Currently the IP address of a device is defined a so-called representation property. This optional property contains the name of a property whose value can be used to uniquely identify a device. The representation property is being used to auto-ignore discovery results of devices that already have a corresponding thing (see Representation Property).

Taking your comments about the ips into account it currently is handled wrong by the binding. I removed the representation property and uploaded a new test version in my current PR. Maybe you can test it once again and verify if discovery is working again. Please remember to re-add existing things to be sure that existing configurations will be updated.


(Chris Colden) #19

I have just removed all chromecast things and forced a scan, all audios and audio groups showed in the inbox. I then added them as things without linking any items to them and looked at the ip of the groups. Tends to be my lounge one as it has the strongest signal to the wifi.

As a test I unplugged the lounge audio to force the groups to move to another member and watched the things go offline in paper ui. Around 60 seconds later, the groups came back online. The ip’s had updated for each of the audio group things which had moved.

I think you have just fixed my issue with fixing the discovery element. I will perform more tests and keep you posted, but I’d say its looking good.

Many thanks, this has been a major bug bare of mine for some time.

Chris


(Chris Colden) #20

Hang on, I seem to have lost the stop channel. Is that right?

Edit: Got the channel back. Will redo the testing.

Edit 2: tests still positive, ips have been updated. I think it added a thing with the same id as previously as all my items were linked.