82f1fa6eb89943d03a4f348621767a857d944418
[python_utils.git] / smart_home / device.py
1 #!/usr/bin/env python3
2
3 """Most basic definition of a smart device: it must have a name and a
4 MAC address and may have some optional keywords.  All devices have
5 these whether they are lights, outlets, thermostats, etc..."""
6
7 import re
8 from typing import List, Optional
9
10 import arper
11
12
13 class Device(object):
14     """Most basic definition of a smart device: it must have a name and a
15     MAC address and may have some optional keywords.  All devices have
16     these whether they are lights, outlets, thermostats, etc..."""
17
18     def __init__(
19         self,
20         name: str,
21         mac: str,
22         keywords: Optional[str] = "",
23     ):
24         self.name = name
25         self.mac = mac
26         self.keywords = keywords
27         self.arper = arper.Arper()
28         if keywords is not None:
29             self.kws: List[str] = keywords.split(' ')
30         else:
31             self.kws = []
32
33     def get_name(self) -> str:
34         return self.name
35
36     def get_mac(self) -> str:
37         return self.mac
38
39     def get_ip(self) -> Optional[str]:
40         return self.arper.get_ip_by_mac(self.mac)
41
42     def has_static_ip(self) -> bool:
43         for kw in self.kws:
44             m = re.search(r'static:([\d\.]+)', kw)
45             if m is not None:
46                 ip = m.group(1)
47                 assert self.get_ip() == ip
48                 return True
49         return False
50
51     # Add command -> URL logic here.
52
53     def get_keywords(self) -> Optional[List[str]]:
54         return self.kws
55
56     def has_keyword(self, keyword: str) -> bool:
57         for kw in self.kws:
58             if kw == keyword:
59                 return True
60         return False
61
62     def get_on_limit_seconds(self) -> Optional[int]:
63         for kw in self.kws:
64             m = re.search(r"timeout:(\d+)", kw)
65             if m is not None:
66                 return int(m.group(1)) * 60
67         return None