diff options
| author | Scott Gasch <[email protected]> | 2022-04-30 10:59:48 -0700 |
|---|---|---|
| committer | Scott Gasch <[email protected]> | 2022-04-30 10:59:48 -0700 |
| commit | f2901184ccb5415cf40b3ec61c128a6a59ab3aa7 (patch) | |
| tree | f9c29997f888de27fe129728b65c854b8454de89 /smart_home | |
| parent | 6fd34b009eec9cda18f1bdd9d8184b7a317a156d (diff) | |
Add some docs and doctests to things that have 0% coverage.
Diffstat (limited to 'smart_home')
| -rw-r--r-- | smart_home/cameras.py | 8 | ||||
| -rw-r--r-- | smart_home/chromecasts.py | 2 | ||||
| -rw-r--r-- | smart_home/registry.py | 52 | ||||
| -rw-r--r-- | smart_home/thermometers.py | 23 |
4 files changed, 79 insertions, 6 deletions
diff --git a/smart_home/cameras.py b/smart_home/cameras.py index 8643611..e8f164b 100644 --- a/smart_home/cameras.py +++ b/smart_home/cameras.py @@ -5,6 +5,7 @@ """Utilities for dealing with the webcams.""" import logging +from typing import Optional import scott_secrets import smart_home.device as dev @@ -29,9 +30,12 @@ class BaseCamera(dev.Device): super().__init__(name.strip(), mac.strip(), keywords) self.camera_name = BaseCamera.camera_mapping.get(name, None) - def get_stream_url(self) -> str: + def get_stream_url(self) -> Optional[str]: + """Get the URL for the webcam's live stream. Return None on error.""" + name = self.camera_name - assert name is not None + if not name: + return None if name == 'driveway': return f'http://10.0.0.226:8080/{scott_secrets.SHINOBI_KEY1}/mjpeg/{scott_secrets.SHINOBI_KEY2}/driveway' else: diff --git a/smart_home/chromecasts.py b/smart_home/chromecasts.py index 408ccf0..3bd45f1 100644 --- a/smart_home/chromecasts.py +++ b/smart_home/chromecasts.py @@ -2,7 +2,7 @@ # © Copyright 2021-2022, Scott Gasch -"""Utilities for dealing with the webcams.""" +"""Utilities for dealing with the chromecasts.""" import atexit import datetime diff --git a/smart_home/registry.py b/smart_home/registry.py index d63474d..8ca7f3b 100644 --- a/smart_home/registry.py +++ b/smart_home/registry.py @@ -83,9 +83,9 @@ class SmartHomeRegistry(object): self._keywords_by_name[name] = keywords self._keywords_by_mac[mac] = keywords self._names_by_mac[mac] = name - self.index_device(name, keywords, mac) + self._index_device(name, keywords, mac) - def index_device(self, name: str, keywords: str, mac: str) -> None: + def _index_device(self, name: str, keywords: str, mac: str) -> None: properties = [("name", name)] tags = set() for kw in keywords.split(): @@ -111,9 +111,30 @@ class SmartHomeRegistry(object): return s def get_keywords_by_name(self, name: str) -> Optional[str]: + """Given the name of a device, get its keywords. + + >>> reg = SmartHomeRegistry('/home/scott/bin/network_mac_addresses.txt') + >>> reg.get_keywords_by_name('near_kitchen_lamp') + 'wifi smart light goog meross test' + + >>> reg.get_keywords_by_name('unknown') is None + True + + """ return self._keywords_by_name.get(name, None) def get_macs_by_name(self, name: str) -> Set[str]: + """Given the name of a device, get its MAC address(es) + + >>> reg = SmartHomeRegistry('/home/scott/bin/network_mac_addresses.txt') + >>> reg.get_macs_by_name('near_kitchen_lamp') + {'34:29:8F:12:34:8E'} + + >>> reg.get_macs_by_name('unknown') + set() + + """ + retval = set() for (mac, lname) in self._names_by_mac.items(): if name in lname: @@ -121,6 +142,19 @@ class SmartHomeRegistry(object): return retval def get_macs_by_keyword(self, keyword: str) -> Set[str]: + """Given a keyword, return the set of MAC address(es) that have + that keyword. + + >>> reg = SmartHomeRegistry('/home/scott/bin/network_mac_addresses.txt') + >>> r = reg.get_macs_by_keyword('test') + >>> e = set(['34:29:8F:12:26:74' , '34:29:8F:12:34:8E']) + >>> r == e + True + + >>> reg.get_macs_by_keyword('unknown') + set() + + """ retval = set() for (mac, keywords) in self._keywords_by_mac.items(): if keyword in keywords: @@ -128,11 +162,15 @@ class SmartHomeRegistry(object): return retval def get_device_by_name(self, name: str) -> Optional[device.Device]: + """Given a name, return its Device object.""" + if name in self._macs_by_name: return self.get_device_by_mac(self._macs_by_name[name]) return None def get_all_devices(self) -> List[device.Device]: + """Return a list of all known devices.""" + retval = [] for mac, _ in self._keywords_by_mac.items(): if mac is not None: @@ -142,6 +180,8 @@ class SmartHomeRegistry(object): return retval def get_device_by_mac(self, mac: str) -> Optional[device.Device]: + """Given a MAC address, return its Device object.""" + if mac in self._keywords_by_mac: name = self._names_by_mac[mac] kws = self._keywords_by_mac[mac] @@ -197,7 +237,7 @@ class SmartHomeRegistry(object): return None def query(self, query: str) -> List[device.Device]: - """Evaluates a lighting query expression formed of keywords to search + """Evaluates a device query expression formed of keywords to search for, logical operators (and, or, not), and parenthesis. Returns a list of matching lights. """ @@ -211,3 +251,9 @@ class SmartHomeRegistry(object): if dev is not None: retval.append(dev) return retval + + +if __name__ == '__main__': + import doctest + + doctest.testmod() diff --git a/smart_home/thermometers.py b/smart_home/thermometers.py index 73117bc..4531c61 100644 --- a/smart_home/thermometers.py +++ b/smart_home/thermometers.py @@ -28,6 +28,22 @@ class ThermometerRegistry(object): } def read_temperature(self, location: str, *, convert_to_fahrenheit=False) -> Optional[float]: + """Read the current value of a thermometer (in celsius unless + convert_to_fahrenheit is True) and return it. Return None on + error. + + >>> registry = ThermometerRegistry() + >>> registry.read_temperature('unknown') is None + True + + >>> temp = registry.read_temperature('house_computer_closet') + >>> temp is None + False + >>> temp > 0.0 + True + + """ + record = self.thermometers.get(location, None) if record is None: logger.error( @@ -36,6 +52,7 @@ class ThermometerRegistry(object): self.thermometers.keys(), ) return None + url = f'http://{record[0]}/~pi/{record[1]}' logger.debug('Constructed URL: %s', url) try: @@ -54,3 +71,9 @@ class ThermometerRegistry(object): if www is not None: www.close() return temp + + +if __name__ == '__main__': + import doctest + + doctest.testmod() |
