Add some docs and doctests to things that have 0% coverage.
[python_utils.git] / smart_home / thermometers.py
index fe5eed18d28ef2851f9bbc6589ff528bfd2060f5..4531c618fc17b749f172abaa301863646f67a0a0 100644 (file)
@@ -1,13 +1,19 @@
 #!/usr/bin/env python3
 
+# © Copyright 2021-2022, Scott Gasch
+
+"""Code involving querying various smart home thermometers."""
+
 import logging
-from typing import Optional
 import urllib.request
+from typing import Optional
 
 logger = logging.getLogger()
 
 
 class ThermometerRegistry(object):
+    """A registry of thermometer hosts / names and how to talk with them."""
+
     def __init__(self):
         self.thermometers = {
             'house_outside': ('10.0.0.75', 'outside_temp'),
@@ -21,30 +27,53 @@ class ThermometerRegistry(object):
             'cabin_hottub': ('192.168.0.107', 'hottub_temp'),
         }
 
-    def read_temperature(
-            self, location: str, *, convert_to_fahrenheit=False
-    ) -> Optional[float]:
+    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(
-                f'Location {location} is not known.  Valid locations are {self.thermometers.keys()}.'
+                'Location %s is not known.  Valid locations are %s.',
+                location,
+                self.thermometers.keys(),
             )
             return None
+
         url = f'http://{record[0]}/~pi/{record[1]}'
-        logger.debug(f'Constructed URL: {url}')
+        logger.debug('Constructed URL: %s', url)
         try:
             www = urllib.request.urlopen(url, timeout=3)
             temp = www.read().decode('utf-8')
             temp = float(temp)
             if convert_to_fahrenheit:
-                temp *= (9/5)
+                temp *= 9 / 5
                 temp += 32.0
                 temp = round(temp)
         except Exception as e:
             logger.exception(e)
-            logger.error(f'Failed to read temperature at URL: {url}')
+            logger.error('Failed to read temperature at URL: %s', url)
             temp = None
         finally:
             if www is not None:
                 www.close()
         return temp
+
+
+if __name__ == '__main__':
+    import doctest
+
+    doctest.testmod()