Ugh, a bunch of things. @overrides. --lmodule. Chromecasts. etc...
[python_utils.git] / smart_home / chromecasts.py
1 #!/usr/bin/env python3
2
3 """Utilities for dealing with the webcams."""
4
5 import logging
6 import time
7
8 import pychromecast
9
10 from decorator_utils import memoized
11 import smart_home.device as dev
12
13 logger = logging.getLogger(__name__)
14
15
16 class BaseChromecast(dev.Device):
17     def __init__(self, name: str, mac: str, keywords: str = "") -> None:
18         super().__init__(name.strip(), mac.strip(), keywords)
19         ip = self.get_ip()
20         self.cast = pychromecast.Chromecast(ip)
21         self.cast.wait()
22         time.sleep(0.1)
23
24     def is_idle(self):
25         return self.cast.is_idle
26
27     @memoized
28     def get_uuid(self):
29         return self.cast.uuid
30
31     @memoized
32     def get_friendly_name(self):
33         return self.cast.name
34
35     def get_uri(self):
36         return self.cast.url
37
38     @memoized
39     def get_model_name(self):
40         return self.cast.model_name
41
42     @memoized
43     def get_cast_type(self):
44         return self.cast.cast_type
45
46     @memoized
47     def app_id(self):
48         return self.cast.app_id
49
50     def get_app_display_name(self):
51         return self.cast.app_display_name
52
53     def get_media_controller(self):
54         return self.cast.media_controller
55
56     def status(self):
57         if self.is_idle():
58             return 'idle'
59         app = self.get_app_display_name()
60         mc = self.get_media_controller()
61         status = mc.status
62         return f'{app} / {status.title}'
63
64     def start_app(self, app_id, force_launch=False):
65         """Start an app on the Chromecast."""
66         self.cast.start_app(app_id, force_launch)
67
68     def quit_app(self):
69         """Tells the Chromecast to quit current app_id."""
70         self.cast.quit_app()
71
72     def volume_up(self, delta=0.1):
73         """Increment volume by 0.1 (or delta) unless it is already maxed.
74         Returns the new volume.
75         """
76         return self.cast.volume_up(delta)
77
78     def volume_down(self, delta=0.1):
79         """Decrement the volume by 0.1 (or delta) unless it is already 0.
80         Returns the new volume.
81         """
82         return self.cast.volume_down(delta)
83
84     def __repr__(self):
85         return (
86             f"Chromecast({self.cast.socket_client.host!r}, port={self.cast.socket_client.port!r}, "
87             f"device={self.cast.device!r})"
88         )