Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How can I tell when an app stops casting? #84

Open
rossdargan opened this issue Apr 21, 2016 · 2 comments
Open

How can I tell when an app stops casting? #84

rossdargan opened this issue Apr 21, 2016 · 2 comments

Comments

@rossdargan
Copy link

I'm really new the python so sorry if this is obvious!

I'm using the code from here: https://www.reddit.com/r/homeautomation/comments/4fc01z/quick_question_for_openhab_users/d28vnc4 to hook up to openhab.

What I want to happen is when I cast something to a chromecast I want me speakers to turn on, and turn off when I stop casting.

The issue I'm having is that the following code:

` self.device.media_controller.register_status_listener(self)

    def new_media_status(self, status):
            self.sendDeviceStatus()

`

doesn't appear to execute when the app_id gets set to None. Is there another "event" I can hook up to so I know when the cast has stopped?

Sorry, I know this is a terrible way to reach out for help, but I didn't want to message you on reddit, and wasn't sure where else to ask!

@noob-4-life
Copy link
Contributor

Not sure if this is what you're looking for, but you can register a listener for new 'cast' (receiver) status updates ??

In the code you linked to, you can add

def __init__(self, device):
    self.device = device
    self.thumbnail = ""
    self.sendDeviceStatus()
    self.device.media_controller.register_status_listener(self)
    self.device.register_status_listener(self)  # Register for receiver status updates.

def new_cast_status(self, new_status):
""" Called when a new status received from the Chromecast. """
    if new_status.app_id != "CC1AD845":
        pass  # Your code to turn off your speakers can go here.

Note that you may want to launch the app on the receiver BEFORE registering the cast/receiver status listener. Otherwise you might end up turning off your speakers before you've started playing anything due to the status being updated for whatever reason. Hope that helps.

P.s. There's also a listener for Network Connection Status updates as well:

def __init__(self, device)
    self.device.register_connection_listener(self)

def new_connection_status(self, new_status):
    # new_status.status will be one of the CONNECTION_STATUS_ constants defined in the
    # socket_client module.
    if new_status.status == CONNECTION_STATUS_DISCONNECTED:
        pass  # Your code to turn off your speakers here.

@henfri
Copy link

henfri commented Nov 6, 2016

Hello,

I am trying the same. I am not sure, I implemented your suggestion correctly:
`#!/usr/bin/python
#source https://www.reddit.com/r/homeautomation/comments/4fc01z/quick_question_for_openhab_users/d28vnc4/
from future import print_function
import pychromecast
import os

def getDeviceNamed(name):
for myDevice in myDevices:
if myDevice.device.name == name:
return myDevice
return None;

def on_mqtt_connect(client, userdata, flags, rc):
for device in devices:
client.subscribe("chromecast/{0}/command".format(device.name))

def on_message(command,device):

try:

            if command[0] == "play":
                    getDeviceNamed(device).device.media_controller.play()
                    getDeviceNamed(device).forceUpdate()
            if command[0] == "pause":
                    getDeviceNamed(device).device.media_controller.pause()
                    getDeviceNamed(device).forceUpdate()
            if command[0] == "stop":
                    getDeviceNamed(device).device.quit_app()
                    getDeviceNamed(device).forceUpdate()
            if command[0] == "volume_up":
                    getDeviceNamed(device).device.volume_up()
                    getDeviceNamed(device).forceUpdate()
            if command[0] == "volume_down":
                    getDeviceNamed(device).device.volume_down()
                    getDeviceNamed(device).forceUpdate()


            if command[0] == "set_volume":
                    print("vol: " + str(command[1]))
                    getDeviceNamed(device).device.set_volume(float(str(command[1])) / 100)
                    getDeviceNamed(device).forceUpdate()

            if command[0] == "replay":
                    getDeviceNamed(device).device.media_controller.seek(getDeviceNamed(device).media_controller.status.current_time - float(str(command[1])))
                    getDeviceNamed(device).forceUpdate()
            if command[0] == "skip":
                    getDeviceNamed(device).device.media_controller.seek(getDeviceNamed(device).media_controller.status.current_time + float(str(command[1])))
                    getDeviceNamed(device).forceUpdate()

            if command[0] == "reboot":
                    getDeviceNamed(device).device.reboot()

            if command[0] == "update":
                    getDeviceNamed(device).forceUpdate()

except:

pass

class DeviceStatusUpdater:
def init(self, device):
self.device = device
self.thumbnail = ""
self.sendDeviceStatus()
self.device.media_controller.register_status_listener(self)

    def new_media_status(self, status):
            self.sendDeviceStatus()

    def forceUpdate(self):
            self.device.socket_client._force_recon=True

    def addDeviceInfo(self, topic, payload):
            return {"topic":"chromecast/{0}/{1}".format(str(self.device.name), topic), "payload":payload}

    def __init__(self, device):
        self.device = device
        self.thumbnail = ""
        self.sendDeviceStatus()
        self.device.media_controller.register_status_listener(self)
        self.device.register_status_listener(self)  # Register for receiver status updates.
        self.device.register_connection_listener(self)


    def new_cast_status(self, new_status):
        #""" Called when a new status received from the Chromecast. """
        print(new_status.app_id)
        if new_status.app_id != "CC1AD845":
            print("NewStatus")
            pass  # Your code to turn off your speakers can go here.


    def new_connection_status(self, new_status):
        # new_status.status will be one of the CONNECTION_STATUS_ constants defined in the
        # socket_client module.
        if new_status.status == CONNECTION_STATUS_DISCONNECTED:
            pass  # Your code to turn off your speakers here.

    def sendDeviceStatus(self):
            #global publish
            deviceInfo = []

            deviceInfo.append(self.addDeviceInfo("name", self.device.name))
            deviceInfo.append(self.addDeviceInfo("host", self.device.host))
            deviceInfo.append(self.addDeviceInfo("app",  self.device.app_display_name))

            if self.device.media_controller is not None:
                    if self.device.media_controller.status is not None:
                            deviceInfo.append(self.addDeviceInfo("state", self.device.media_controller.status.player_state))

                            if self.device.media_controller.status.player_state == pychromecast.controllers.media.MEDIA_PLAYER_STATE_PLAYING:
                                    deviceInfo.append(self.addDeviceInfo("is_playing", "ON"))
                            else:
                                    deviceInfo.append(self.addDeviceInfo("is_playing", "OFF"))

                            deviceInfo.append(self.addDeviceInfo("title",                   self.device.media_controller.status.title))
                            deviceInfo.append(self.addDeviceInfo("series_title",            self.device.media_controller.status.series_title))
                            deviceInfo.append(self.addDeviceInfo("artist",                  self.device.media_controller.status.artist))
                            deviceInfo.append(self.addDeviceInfo("album",                   self.device.media_controller.status.album_name))
                            deviceInfo.append(self.addDeviceInfo("mediatype",               self.device.media_controller.status.metadata_type))
                            deviceInfo.append(self.addDeviceInfo("thumbnail",               self.device.media_controller.thumbnail))
                            deviceInfo.append(self.addDeviceInfo("volume",                  str(float(self.device.status.volume_level) * 100)))
                            deviceInfo.append(self.addDeviceInfo("current",                 self.device.media_controller.status.current_time))

                            duration = self.device.media_controller.status.duration
                            if duration is None:
                                    duration = -1
                            deviceInfo.append(self.addDeviceInfo("duration",                duration))


                            if self.thumbnail is not self.device.media_controller.thumbnail:
                  #                  os.system("wget {1} -O /usr/share/openhab/webapps/images/{0}.png".format(self.device.name, self.device.media_controller.thumbnail))
                                    #os.system("/usr/bin/convert /usr/share/openhab/webapps/images/{0}.png -resize 128x128 /usr/share/openhab/webapps/images/{0}.png".format(self.device.name))
                                    self.thumbnail = self.device.media_controller.thumbnail


                            print(deviceInfo)

print ("Device discovery...")
devices = pychromecast.get_chromecasts()
global myDevices
myDevices = []
for device in devices:
# Wait for cast device to be ready
device.wait()
print(str(device))
myDevices.append(DeviceStatusUpdater(device))

myDevices is a list of Chromecast devices (class DeviceStatusUpdater)

we can now send a message

cmd=['set_volume', '33']
on_message(cmd,"ChromecastSchlafzimmer")

or get the Title

print(myDevices[0].sendDeviceStatus)

from time import sleep

while True:
sleep(1)`

What happens is, that I get this output:
vol: 33
<bound method DeviceStatusUpdater.sendDeviceStatus of <main.DeviceStatusUpdater object at 0x7f97736875f8>>
Error communicating with socket, resetting connection
233637DE
NewStatus

Followed by the output of sendDeviceStatus()

But when changing the status of the chromecast (play, pause, ...) only
sendDeviceStatus is called, whereas new_cast_status is not called.

new_cast_status is only called upon launch of the script.

Also: What could be the error of the message
"Error communicating with socket, resetting connection"

Regards,
Hendrik

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants