def was_file_written_today(filename: str) -> bool:
- """Returns True if filename was written today."""
+ """Returns True if filename was written today.
+
+ >>> import os
+ >>> filename = f'/tmp/testing_persistent_py_{os.getpid()}'
+ >>> os.system(f'touch {filename}')
+ 0
+ >>> was_file_written_today(filename)
+ True
+ >>> os.system(f'touch -d 1974-04-15T01:02:03.99 {filename}')
+ 0
+ >>> was_file_written_today(filename)
+ False
+ >>> os.system(f'/bin/rm -f {filename}')
+ 0
+ >>> was_file_written_today(filename)
+ False
+ """
if not file_utils.does_file_exist(filename):
return False
"""Returns True if filename was written within the pas limit_seconds
seconds.
+ >>> import os
+ >>> filename = f'/tmp/testing_persistent_py_{os.getpid()}'
+ >>> os.system(f'touch {filename}')
+ 0
+ >>> was_file_written_within_n_seconds(filename, 60)
+ True
+ >>> import time
+ >>> time.sleep(2.0)
+ >>> was_file_written_within_n_seconds(filename, 2)
+ False
+ >>> os.system(f'/bin/rm -f {filename}')
+ 0
+ >>> was_file_written_within_n_seconds(filename, 60)
+ False
"""
+
if not file_utils.does_file_exist(filename):
return False
return self.instance
return _load
+
+
+if __name__ == '__main__':
+ import doctest
+
+ doctest.testmod()
"""Utilities for dealing with the webcams."""
import logging
+from typing import Optional
import scott_secrets
import smart_home.device as dev
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:
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():
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:
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:
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:
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]
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.
"""
if dev is not None:
retval.append(dev)
return retval
+
+
+if __name__ == '__main__':
+ import doctest
+
+ doctest.testmod()
}
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(
self.thermometers.keys(),
)
return None
+
url = f'http://{record[0]}/~pi/{record[1]}'
logger.debug('Constructed URL: %s', url)
try:
if www is not None:
www.close()
return temp
+
+
+if __name__ == '__main__':
+ import doctest
+
+ doctest.testmod()