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