Skip to content

Commit b1cd262

Browse files
emontnemeryballoob
authored andcommitted
Do not automatically start worker thread and connect in Chromecast constructor (#271)
* Add defer_connect option to Chromecast class constructor * Lint * Do not connect or start thread in socket_client constructor * Fix non-blocking mode, update examples * Start worker thread from Chromecast.wait() * Lint * Lint
1 parent 85e0b6a commit b1cd262

File tree

8 files changed

+48
-16
lines changed

8 files changed

+48
-16
lines changed

README.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ How to use
3939
['Dev', 'Living Room', 'Den', 'Bedroom']
4040
4141
>> cast = next(cc for cc in chromecasts if cc.device.friendly_name == "Living Room")
42-
>> # Wait for cast device to be ready
42+
>> # Start worker thread and wait for cast device to be ready
4343
>> cast.wait()
4444
>> print(cast.device)
4545
DeviceStatus(friendly_name='Living Room', model_name='Chromecast', manufacturer='Google Inc.', uuid=UUID('df6944da-f016-4cb8-97d0-3da2ccaa380b'), cast_type='cast')

examples/blocking.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
print("No Devices Found")
2020
exit()
2121
cast = casts[0]
22+
cast.start()
2223

2324
print()
2425
print(cast.device)

examples/dashcast_blocking.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
exit()
2222

2323
cast = casts[0]
24+
cast.start()
2425

2526
d = dashcast.DashCastController()
2627
cast.register_handler(d)

examples/non_blocking.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ def your_main_loop():
2020
t = 1
2121
cast = None
2222
def callback(chromecast):
23+
chromecast.connect()
2324
nonlocal cast
2425
cast = chromecast
2526
stop_discovery()

examples/simple_listener_example.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ def new_media_status(self, status):
3030
chromecasts = pychromecast.get_chromecasts()
3131
chromecast = next(cc for cc in chromecasts
3232
if cc.device.friendly_name == "Living Room Speaker")
33+
chromecast.start()
3334

3435
listenerCast = StatusListener(chromecast.name, chromecast)
3536
chromecast.register_status_listener(listenerCast)

examples/spotify_example.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
chromecasts = pychromecast.get_chromecasts()
1515
cast = chromecasts[0]
16+
cast.start()
1617

1718
CAST_NAME = "My Chromecast"
1819
device_id = None

pychromecast/__init__.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ def internal_stop():
119119
return internal_stop
120120

121121

122-
# pylint: disable=too-many-instance-attributes
122+
# pylint: disable=too-many-instance-attributes, too-many-public-methods
123123
class Chromecast(object):
124124
"""
125125
Class to interface with a ChromeCast.
@@ -206,9 +206,6 @@ def __init__(self, host, port=None, device=None, **kwargs):
206206
self.register_connection_listener = \
207207
self.socket_client.register_connection_listener
208208

209-
if blocking:
210-
self.socket_client.start()
211-
212209
@property
213210
def ignore_cec(self):
214211
""" Returns whether the CEC data should be ignored. """
@@ -320,15 +317,26 @@ def wait(self, timeout=None):
320317
Waits until the cast device is ready for communication. The device
321318
is ready as soon a status message has been received.
322319
320+
If the worker thread is not already running, it will be started.
321+
323322
If the status has already been received then the method returns
324323
immediately.
325324
326325
:param timeout: a floating point number specifying a timeout for the
327326
operation in seconds (or fractions thereof). Or None
328327
to block forever.
329328
"""
329+
if not self.socket_client.isAlive():
330+
self.socket_client.start()
330331
self.status_event.wait(timeout=timeout)
331332

333+
def connect(self):
334+
""" Connect to the chromecast.
335+
336+
Must only be called if the worker thread will not be started.
337+
"""
338+
self.socket_client.connect()
339+
332340
def disconnect(self, timeout=None, blocking=True):
333341
"""
334342
Disconnects the chromecast and waits for it to terminate.
@@ -354,6 +362,12 @@ def join(self, timeout=None):
354362
"""
355363
self.socket_client.join(timeout=timeout)
356364

365+
def start(self):
366+
"""
367+
Start the chromecast connection's worker thread.
368+
"""
369+
self.socket_client.start()
370+
357371
def __del__(self):
358372
try:
359373
self.socket_client.stop.set()

pychromecast/socket_client.py

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -212,14 +212,6 @@ def __init__(self, host, port=None, cast_type=CAST_TYPE_CHROMECAST,
212212

213213
self.receiver_controller.register_status_listener(self)
214214

215-
try:
216-
self.initialize_connection()
217-
except ChromecastConnectionError:
218-
self._report_connection_status(
219-
ConnectionStatus(CONNECTION_STATUS_DISCONNECTED,
220-
NetworkAddress(self.host, self.port)))
221-
raise
222-
223215
def initialize_connection(self): # noqa: E501 pylint:disable=too-many-statements, too-many-branches
224216
"""Initialize a socket to a Chromecast, retrying as necessary."""
225217
tries = self.tries
@@ -361,6 +353,19 @@ def mdns_backoff(service, retry):
361353
self.fn or self.host, self.port)
362354
raise ChromecastConnectionError("Failed to connect")
363355

356+
def connect(self):
357+
""" Connect socket connection to Chromecast device.
358+
359+
Must only be called if the worker thread will not be started.
360+
"""
361+
try:
362+
self.initialize_connection()
363+
except ChromecastConnectionError:
364+
self._report_connection_status(
365+
ConnectionStatus(CONNECTION_STATUS_DISCONNECTED,
366+
NetworkAddress(self.host, self.port)))
367+
return
368+
364369
def disconnect(self):
365370
""" Disconnect socket connection to Chromecast device """
366371
self.stop.set()
@@ -413,7 +418,15 @@ def is_stopped(self):
413418
return self.stop.is_set()
414419

415420
def run(self):
416-
""" Start polling the socket. """
421+
""" Connect to the cast and start polling the socket. """
422+
try:
423+
self.initialize_connection()
424+
except ChromecastConnectionError:
425+
self._report_connection_status(
426+
ConnectionStatus(CONNECTION_STATUS_DISCONNECTED,
427+
NetworkAddress(self.host, self.port)))
428+
return
429+
417430
self.heartbeat_controller.reset()
418431
self._force_recon = False
419432
logging.debug("Thread started...")
@@ -698,8 +711,8 @@ def send_message(self, destination_id, namespace, data,
698711
self.logger.info('[%s:%s] Error writing to socket.',
699712
self.fn or self.host, self.port)
700713
else:
701-
raise NotConnected("Chromecast " + self.host + ":" + self.port +
702-
" is connecting...")
714+
raise NotConnected("Chromecast " + self.host + ":" +
715+
str(self.port) + " is connecting...")
703716

704717
def send_platform_message(self, namespace, message, inc_session_id=False,
705718
callback_function_param=False):

0 commit comments

Comments
 (0)