3 """Utilities for dealing with the webcams."""
9 from typing import Any, List
13 import smart_home.device as dev
14 from decorator_utils import memoized
16 logger = logging.getLogger(__name__)
19 class BaseChromecast(dev.Device):
20 ccasts: List[Any] = []
23 lock = threading.Lock()
25 def __init__(self, name: str, mac: str, keywords: str = "") -> None:
26 super().__init__(name.strip(), mac.strip(), keywords)
28 now = datetime.datetime.now()
29 with BaseChromecast.lock:
31 BaseChromecast.refresh_ts is None
32 or (now - BaseChromecast.refresh_ts).total_seconds() > 60
34 logger.debug('Refreshing the shared chromecast info list')
35 if BaseChromecast.browser is not None:
36 BaseChromecast.browser.stop_discovery()
38 BaseChromecast.ccasts,
39 BaseChromecast.browser,
40 ) = pychromecast.get_chromecasts(timeout=15.0)
41 assert BaseChromecast.browser is not None
42 atexit.register(BaseChromecast.browser.stop_discovery)
43 BaseChromecast.refresh_ts = now
46 for cc in BaseChromecast.ccasts:
47 if cc.cast_info.host == ip and cc.cast_info.cast_type != 'group':
48 logger.debug(f'Found chromecast at {ip}: {cc}')
50 self.cast.wait(timeout=1.0)
53 f'Can\'t find ccast device at {ip}, is that really a ccast device?'
57 return self.cast.is_idle
64 def get_friendly_name(self):
71 def get_model_name(self):
72 return self.cast.model_name
75 def get_cast_type(self):
76 return self.cast.cast_type
80 return self.cast.app_id
82 def get_app_display_name(self):
83 return self.cast.app_display_name
85 def get_media_controller(self):
86 return self.cast.media_controller
91 app = self.get_app_display_name()
92 mc = self.get_media_controller()
94 return f'{app} / {status.title}'
96 def start_app(self, app_id, force_launch=False):
97 """Start an app on the Chromecast."""
98 self.cast.start_app(app_id, force_launch)
101 """Tells the Chromecast to quit current app_id."""
104 def volume_up(self, delta=0.1):
105 """Increment volume by 0.1 (or delta) unless it is already maxed.
106 Returns the new volume.
108 return self.cast.volume_up(delta)
110 def volume_down(self, delta=0.1):
111 """Decrement the volume by 0.1 (or delta) unless it is already 0.
112 Returns the new volume.
114 return self.cast.volume_down(delta)
118 f"Chromecast({self.cast.socket_client.host!r}, port={self.cast.socket_client.port!r}, "
119 f"device={self.cast.cast_info.friendly_name!r})"