Make PresenceDetection self-update periodically.
authorScott <[email protected]>
Mon, 6 Dec 2021 05:43:24 +0000 (21:43 -0800)
committerScott <[email protected]>
Mon, 6 Dec 2021 05:43:24 +0000 (21:43 -0800)
presence.py

index 477b14ffa0a83c2a0cf8c18a90ab6537953cfeda..b32a218b95f0876949752e669dfa6ced62199e6e 100755 (executable)
@@ -28,6 +28,13 @@ cfg.add_argument(
     metavar="FILENAME",
     help="The location of persisted_mac_addresses.txt to use."
 )
+cfg.add_argument(
+    '--presence_tolerable_staleness_seconds',
+    type=argparse_utils.valid_duration,
+    default=datetime.timedelta(seconds=60 * 5),
+    metavar='DURATION',
+    help='Max acceptable age of location data before auto-refreshing'
+)
 
 
 class PresenceDetection(object):
@@ -67,7 +74,19 @@ class PresenceDetection(object):
         ] = defaultdict(dict)
         self.names_by_mac: Dict[str, str] = {}
         self.dark_locations: Set[Location] = set()
-        self.update()
+        self.last_update = None
+
+    def maybe_update(self) -> None:
+        if self.last_update is None:
+            self.update()
+        else:
+            now = datetime.datetime.now()
+            delta = now - self.last_update
+            if delta.total_seconds() > config.config['presence_tolerable_staleness_seconds'].total_seconds():
+                logger.debug(
+                    f"It's been {delta.total_seconds()}s since last update; refreshing now."
+                )
+                self.update()
 
     def update(self) -> None:
         self.dark_locations = set()
@@ -77,6 +96,7 @@ class PresenceDetection(object):
             self.update_from_cabin()
         else:
             raise Exception("Where the hell is this running?!")
+        self.last_update = datetime.datetime.now()
 
     def update_from_house(self) -> None:
         from exec_utils import cmd_with_timeout
@@ -111,7 +131,7 @@ class PresenceDetection(object):
             self.parse_raw_macs_file(raw, Location.HOUSE)
         except Exception as e:
             logger.exception(e)
-            logger.warning(f"Can't see the house right now; presence detection impared.")
+            logger.warning("Can't see the house right now; presence detection impared.")
             self.dark_locations.add(Location.HOUSE)
 
     def read_persisted_macs_file(
@@ -158,6 +178,7 @@ class PresenceDetection(object):
             self.weird_mac_at_cabin = True
 
     def is_anyone_in_location_now(self, location: Location) -> bool:
+        self.maybe_update()
         if location in self.dark_locations:
             raise Exception("Can't see {location} right now; answer undefined.")
         for person in Person:
@@ -170,7 +191,7 @@ class PresenceDetection(object):
         return False
 
     def where_is_person_now(self, name: Person) -> Location:
-        import dict_utils
+        self.maybe_update()
         if len(self.dark_locations) > 0:
             logger.warning(
                 f"Can't see {self.dark_locations} right now; answer confidence impacted"
@@ -182,6 +203,8 @@ class PresenceDetection(object):
                 return Location.CABIN
             else:
                 return Location.UNKNOWN
+
+        import dict_utils
         votes: Dict[Location, int] = {}
         tiebreaks: Dict[Location, datetime.datetime] = {}
         credit = 10000