Page 2 of 3

Re: Chromecast status

Posted: Tuesday 21 February 2017 15:27
by Ewaldharmsen
I like the idea of this!

I have a chromecast, but no knowledge of python and just a litle bit of domoticz.

Can someone summarize the steps needed?
1) Download pychromecast from github https://github.com/balloob/pychromecast -> where should I download it to/how should I download it?
2) Place the python script in which folder?
3) What should I change - files/lines?

Re: Chromecast status

Posted: Tuesday 21 February 2017 17:36
by sisaenkov
I use curl for this:

Code: Select all

/usr/bin/curl -m 2 -ks http://172.16.1.42:8008/setup/eureka_info | /usr/bin/jq .connected
connected - is the most useful Chromecast parameter for me

Re: Chromecast status

Posted: Tuesday 21 February 2017 22:11
by franzelare
nice! I have to look into this how to integrate this!

Re: RE: Re: Chromecast status

Posted: Wednesday 22 February 2017 10:14
by Varazir
sisaenkov wrote:I use curl for this:

Code: Select all

/usr/bin/curl -m 2 -ks http://172.16.1.42:8008/setup/eureka_info | /usr/bin/jq .connected
connected - is the most useful Chromecast parameter for me
How make that into a continuous check off the CC?

Sent from my Nexus 5 using Tapatalk

Re: Chromecast status

Posted: Wednesday 22 February 2017 10:40
by Varazir
And I need to know if it's playing or not. Mine is always connected.

Sent from my Nexus 5 using Tapatalk

Re: Chromecast status

Posted: Wednesday 22 February 2017 14:26
by sisaenkov
By default there is no such parameter in json output.

Re: Chromecast status

Posted: Thursday 23 February 2017 20:26
by Ewaldharmsen
Got it working using these steps:
• place the unzupped pychromecats folder in the python folder of domoticz
• cd domoticz\scripts\python\pychromecast-master
• sudo apt-get install python-dev
• pip install -r requirements.txt
• sudo python setup.py install

It is retrieving the status correctly, but nthing happens in DOmotics.
Did it even like this:
print("Turning on")
#data = urlopen(self.domurl+"/json.htm?type=command&param=switchlight&idx="+self.device+"&switchcmd=On")
data = urlopen("http://192.168.0.116:8080/json.htm?type ... itchcmd=On")

"Turning on" gets printed, but url looks like never executed...

Re: Chromecast status

Posted: Thursday 23 February 2017 21:32
by Varazir
Ewaldharmsen wrote:Got it working using these steps:
• place the unzupped pychromecats folder in the python folder of domoticz
• cd domoticz\scripts\python\pychromecast-master
• sudo apt-get install python-dev
• pip install -r requirements.txt
• sudo python setup.py install

It is retrieving the status correctly, but nthing happens in DOmotics.
Did it even like this:
print("Turning on")
#data = urlopen(self.domurl+"/json.htm?type=command&param=switchlight&idx="+self.device+"&switchcmd=On")
data = urlopen("http://192.168.0.116:8080/json.htm?type ... itchcmd=On")

"Turning on" gets printed, but url looks like never executed...


I keep getting errors running it on my raspberry pi

Code: Select all

 File "cast.py", line 1
    from __future__ import print_function
    ^
IndentationError: unexpected indent

Traceback (most recent call last):
  File "cast.py", line 7, in <module>
    from urllib.request import urlopen
ImportError: No module named request


Traceback (most recent call last):
  File "cast.py", line 8, in <module>
    from urllib.parse import urlencode
ImportError: No module named parse


Traceback (most recent call last):
  File "cast.py", line 11, in <module>
    import pychromecast.controllers.youtube as youtube
ImportError: No module named controllers.youtube


Traceback (most recent call last):
  File "cast.py", line 19, in <module>
    cast = pychromecast.get_chromecast()
AttributeError: 'module' object has no attribute 'get_chromecast'


Re: Chromecast status

Posted: Friday 24 February 2017 13:23
by Ewaldharmsen
unexpected indent means you have a space or watever wrong in your code.
In Python the outline makes or brakes the code

Re: Chromecast status

Posted: Friday 24 February 2017 13:26
by Ewaldharmsen
my complete code looks like this now:

Code: Select all

from __future__ import print_function
import time
import sys
import logging
import json
import codecs
import urllib
import pychromecast

domoticz = "http://192.168.0.116:8080"

cast = pychromecast.Chromecast("192.168.0.133")
class mediaListener:
    domurl="http://192.168.0.116:8080"
    deviceno=18
    def __init__(self, domoticzurl, deviceno):
        self.domurl = domoticzurl
        self.device=deviceno
        self.oldPlayerStatus = 'NONE'

    def new_media_status(self, status):
        if (self.oldPlayerStatus != status.player_state):
            self.oldPlayerStatus = status.player_state
            if status.player_state == "PLAYING" or status.player_state == "BUFFERING":
				print("Turning on")
				data = urllib.urlopen(self.domurl+"/json.htm?type=command&param=switchlight&idx=18&switchcmd=On")
            else :
				print("Turning off")
				data = urllib.urlopen(self.domurl+"/json.htm?type=command&param=switchlight&idx=18&switchcmd=Off")
            self.storeVariable('ChromeState', new_state)

    def storeVariable(self,name, value):
        value = urlencode({'vvalue':value, 'vname':name, 'vtype':2})
        d = urlopen(self.domurl+'/json.htm?type=command&param=updateuservariable&'+value)
        reader = codecs.getreader("utf-8")
        obj = json.load(reader(d))
        if (obj['status'] == 'ERR'):
            d = urlopen(self.domurl+'/json.htm?type=command&param=saveuservariable&'+value)

listener = mediaListener(domoticz, 18)

cast.media_controller.register_status_listener(listener)


while (1):
	time.sleep(1)  # Delay for 1 second 
I have to hardcode the idx number 18 as self.device does not work somehow

Re: Chromecast status

Posted: Friday 24 February 2017 13:28
by Ewaldharmsen
its working great for youtube but not for netflix.
Then it stops working after 4 changes.


ALso the uservariable does not get updated

Re: Chromecast status

Posted: Friday 24 February 2017 13:34
by Varazir
Moved over to my Ubuntu machine and now I get https://gist.github.com/varazir/851c401 ... 42284f080b

Sent from my Nexus 5 using Tapatalk

Re: Chromecast status

Posted: Friday 24 February 2017 21:02
by Ewaldharmsen
Changed a lot, this script works better, also with Netflix:

Code: Select all

import pychromecast
import pychromecast.controllers
import json
import time
import re
import subprocess
import urllib

print "Script started"

#
# Variables to set. 
#

# IP address of the chromecast to control 
chromecast_ip = "192.168.0.133"
#Address of domoticz
domoticz = "http://192.168.0.116:8080"
# Prefix for all URLs to be handled. E.g. if the application runs on http://localhost/chromecast, 
# the prefix should be "/chromecast"
url_prefix = "/chromecast"

# Timeout to wait for the status (ms)
status_timeout = 5000

#Domoticz DeviceID
IDX="18"

#Variable for old state
OldStatus="idle"

"""
Handles status updates 
"""
class StatusHandler(object):
    def __init__(self, cast):
        """
        Initialize the handler
        cast:              the chromecast object to work with
        """
        self.cast = cast
        self.cast_status = False
        self.media_status = False

    def new_cast_status(self, status):
        self.cast_status = True
        
    def new_media_status(self,status):
    	self.media_status = True

"""
Returns a chromecast object filled with the status
"""
def get_cast_with_status(chromecast_ip):
	cast = pychromecast.Chromecast(host=chromecast_ip)

	# We can only use the controller when a status has been retrieved
	# For that reason, we wait for that event 
	status_handler = StatusHandler(cast)
	cast.socket_client.receiver_controller.register_status_listener(status_handler)
	cast.media_controller.register_status_listener(status_handler)
	
	# Wait for the status, although not forever
	starttime = time.time() * 1000
	wait_until = starttime + status_timeout
	while ( time.time() * 1000 ) < wait_until and not (status_handler.cast_status and status_handler.media_status):
		pass
	
	return cast
#print dir(cast.media_controller.status.player_state)

def get_current_status():
	global OldStatus
	cast = get_cast_with_status(chromecast_ip)#have to do this each time otherwise netflix will not work
	
	#print dir(cast)
	
	if (cast.app_display_name == "Netflix"):
		CurrentStatus=cast.media_controller.status.player_state
		print "Currenstatus",CurrentStatus
		if (OldStatus != CurrentStatus):
			if CurrentStatus == "PLAYING" or CurrentStatus == "BUFFERING":
				print("Turning on")
				data = urllib.urlopen(domoticz+"/json.htm?type=command&param=switchlight&idx="+IDX+"&switchcmd=On")
			else :
				print("Turning off")
				data = urllib.urlopen(domoticz+"/json.htm?type=command&param=switchlight&idx="+IDX+"&switchcmd=Off")
			print "Old status is ",OldStatus
			OldStatus = CurrentStatus
		
while (1):
	get_current_status()
	time.sleep(1)  # Delay for 1 second 		
	
print "Script stopped"

Re: RE: Re: Chromecast status

Posted: Friday 24 February 2017 21:13
by Varazir
Ewaldharmsen wrote:Changed a lot, this script works better, also with Netflix:
Could you post the code in gist.github.com or Ubuntu's pastebin?

Sent from my Nexus 5 using Tapatalk

Re: Chromecast status

Posted: Friday 24 February 2017 21:52
by Varazir
Ewaldharmsen wrote:Changed a lot, this script works better, also with Netflix:
I got a error for each print you in the script so I can't see it have been working

line 9 80 88 and 95

Code: Select all

  File "cast2.py", line 9
    print "Script started"
                         ^
SyntaxError: Missing parentheses in call to 'print'

After adding () to all I got this

Code: Select all

python3 cast2.py
Traceback (most recent call last):
  File "cast2.py", line 2, in <module>
    import pychromecast.controllers
ImportError: No module named 'pychromecast.controllers'

Moved the script to ~/domoticz/scripts/python/pychromecast

Then I get this

Code: Select all

Traceback (most recent call last):
  File "cast2.py", line 1, in <module>
    import pychromecast
  File "/home/pi/domoticz/scripts/python/pychromecast/pychromecast/__init__.py", line 12, in <module>
    from .config import *  # noqa
  File "/home/pi/domoticz/scripts/python/pychromecast/pychromecast/config.py", line 6, in <module>
    import requests
ImportError: No module named 'requests'
Starting it with python 2.7 it worked better but after some time I got this

Code: Select all

python cast2.py
Script started
ERROR:pychromecast.socket_client:Failed to connect, retrying in 5.000000s
Traceback (most recent call last):
  File "/tmp/download/pychromecast/pychromecast/socket_client.py", line 246, in initialize_connection
    self.socket.connect((self.host, self.port))
  File "/usr/lib/python2.7/ssl.py", line 866, in connect
    self._real_connect(addr, False)
  File "/usr/lib/python2.7/ssl.py", line 857, in _real_connect
    self.do_handshake()
  File "/usr/lib/python2.7/ssl.py", line 830, in do_handshake
    self._sslobj.do_handshake()
error: [Errno 104] Connection reset by peer

Re: Chromecast status

Posted: Friday 24 February 2017 22:11
by Ewaldharmsen
you have to replace all occurrences of “except socket.error:” with “except (socket.error,OSError):” in the file pychromecast\socket_client.py

Re: Chromecast status

Posted: Friday 24 February 2017 22:13
by Varazir
Ewaldharmsen wrote:you have to replace all occurrences of “except socket.error:” with “except (socket.error,OSError):” in the file pychromecast\socket_client.py

okay, sound like something isn't right here is the script/modul made for some other system...

I'll give it a try

Code: Select all

Script started
ERROR:pychromecast.socket_client:Failed to connect, retrying in 5.000000s
Traceback (most recent call last):
  File "/tmp/download/pychromecast/pychromecast/socket_client.py", line 246, in initialize_connection
    self.socket.connect((self.host, self.port))
  File "/usr/lib/python2.7/ssl.py", line 866, in connect
    self._real_connect(addr, False)
  File "/usr/lib/python2.7/ssl.py", line 857, in _real_connect
    self.do_handshake()
  File "/usr/lib/python2.7/ssl.py", line 830, in do_handshake
    self._sslobj.do_handshake()
error: [Errno 104] Connection reset by peer

Edit: Python is a mess with versions...

Re: Chromecast status

Posted: Thursday 13 April 2017 16:25
by Chrisiesmit93
Ewaldharmsen wrote:you have to replace all occurrences of “except socket.error:” with “except (socket.error,OSError):” in the file pychromecast\socket_client.py
I also edited the code as mentioned above, but the script evertime stops at exactly 32 "checks" (this also happens when I comment the line with the 1 sec delay).

When the script IS running (first 32 checks), it's running flawlessly. But when the error kicks in, the script is dead. :(

Re: Chromecast status

Posted: Wednesday 17 October 2018 16:51
by moengiant
Heisenberg wrote: Monday 11 January 2016 18:17 Does someone know if it's possible to start a stream through Chromecast (audio) via Domoticz?
Yes, I use my chromecast/google mini's to announce notifications throughout my home. I have two groups set up in Google Home - one for whole house - use this for playing music all around the house - and then another group set-up for notifications (does not include any of the TV's) - as its very annoying when a TV switches over to Chromecast in the middle of a show/game to announce "sunset".

I did this in python using the Chrome and Google TTS python modules. For notifications it passes the notification message off to my script.
Very easy to do - you can check out my script - DomoMatic or DomoWeatherAlert on Github

Any media with a URL/link you can cast/stream

https://github.com/moengiant

Cheers

Re: Chromecast status

Posted: Wednesday 17 October 2018 17:08
by moengiant
tbowmo wrote: Saturday 20 February 2016 18:44 downloaded pychromecast from github https://github.com/balloob/pychromecast

and then using the following python script

Code: Select all

from __future__ import print_function
import time
import sys
import logging
import json
import codecs
from urllib.request import urlopen
from urllib.parse import urlencode

import pychromecast
import pychromecast.controllers.youtube as youtube

domoticz = "http://localhost:8080"


if '--show-debug' in sys.argv:
    logging.basicConfig(level=logging.DEBUG)

cast = pychromecast.get_chromecast()

class mediaListener:
    domurl="http://localhost:8080"
    device=20
    def __init__(self, domoticzurl, deviceno):
        self.domurl = domoticzurl
        self.device=deviceno
        self.oldPlayerStatus = 'NONE'

    def new_media_status(self, status):
        print("mediaListener")
        print(status)
        if (self.oldPlayerStatus != status.player_state):
            self.oldPlayerStatus = status.player_state
            if status.player_state == "PLAYING" or status.player_state == "BUFFERING":
                data = urlopen(self.domurl+"/json.htm?type=command&param=switchlight&idx="+self.device+"&switchcmd=on")
            else :
                data = urlopen(self.domurl+"/json.htm?type=command&param=switchlight&idx="+self.device+"&switchcmd=off")
            self.storeVariable('ChromeState', new_state)

    def storeVariable(self,name, value):
        value = urlencode({'vvalue':value, 'vname':name, 'vtype':2})
        d = urlopen(self.domurl+'/json.htm?type=command&param=updateuservariable&'+value)
        reader = codecs.getreader("utf-8")
        obj = json.load(reader(d))
        if (obj['status'] == 'ERR'):
            d = urlopen(self.domurl+'/json.htm?type=command&param=saveuservariable&'+value)

listener = mediaListener(domoticz, 106)

cast.media_controller.register_status_listener(listener)

while (1):
    pass
It's a draft and seems to work.. Setting a virtual switch on / off, according to the playing state. And also populates a uservariable with the current state.

I don't have any lights connected, so haven't checked how well this works.. (The lights are in development..)
Very nice work. I will have to add this to my running python scripts. It may be easier to trigger a scene rather than hitting devices individually - you could have scenes set for the rooms where you have a Chromecast - playing, pause and stop/off.