Make smart futures avoid polling.
[python_utils.git] / presence.py
index b310183b4da6c1fdf002bee0c559abd9a9fd0ca1..d7db41676a03cff60172ed2b25936f51f3b2cfa0 100755 (executable)
@@ -51,16 +51,14 @@ class PresenceDetection(object):
             Person.SCOTT: [
                 "3C:28:6D:10:6D:41", # pixel3
                 "6C:40:08:AE:DC:2E", # laptop
-#                "D4:61:2E:88:18:09", # watch
-#                "14:7D:DA:6A:20:D7", # work laptop
             ],
             Person.LYNN: [
-                "08:CC:27:63:26:14",
-                "B8:31:B5:9A:4F:19",
+                "08:CC:27:63:26:14", # motog7
+                "B8:31:B5:9A:4F:19", # laptop
             ],
             Person.ALEX: [
-                "0C:CB:85:0C:8B:AE",
-                "D0:C6:37:E3:36:9A",
+                "0C:CB:85:0C:8B:AE", # phone
+                "D0:C6:37:E3:36:9A", # laptop
             ],
             Person.AARON_AND_DANA: [
                 "98:B6:E9:E5:5A:7C",
@@ -149,6 +147,7 @@ class PresenceDetection(object):
 
     def where_is_person_now(self, name: Person) -> Location:
         import dict_utils
+        logger.debug(f'Looking for {name}...')
 
         if name is Person.UNKNOWN:
             if self.weird_mac_at_cabin:
@@ -159,26 +158,30 @@ class PresenceDetection(object):
         tiebreaks: Dict[Location, datetime.datetime] = {}
         credit = 10000
         for mac in self.devices_by_person[name]:
-            logger.debug(f'Looking for {name}... check for mac {mac}')
             if mac not in self.names_by_mac:
                 continue
+            mac_name = self.names_by_mac[mac]
+            logger.debug(f'Looking for {name}... check for mac {mac} ({mac_name})')
             for location in self.location_ts_by_mac:
                 if mac in self.location_ts_by_mac[location]:
                     ts = (self.location_ts_by_mac[location])[mac]
-                    logger.debug(f'I saw {mac} at {location} at {ts}')
+                    logger.debug(f'Seen {mac} ({mac_name}) at {location} since {ts}')
                     tiebreaks[location] = ts
-            location = dict_utils.key_with_min_value(tiebreaks)
-            v = votes.get(location, 0)
-            votes[location] = v + credit
-            logger.debug(f'{name}: {location} gets {credit} votes.')
+
+            (most_recent_location, first_seen_ts) = dict_utils.item_with_max_value(tiebreaks)
+            bonus = credit
+            v = votes.get(most_recent_location, 0)
+            votes[most_recent_location] = v + bonus
+            logger.debug(f'{name}: {location} gets {bonus} votes.')
             credit = int(
-                credit * 0.667
+                credit * 0.2
             )  # Note: list most important devices first
             if credit <= 0:
                 credit = 1
         if len(votes) > 0:
-            item = dict_utils.item_with_max_value(votes)
-            return item[0]
+            (location, value) = dict_utils.item_with_max_value(votes)
+            if value > 2001:
+                return location
         return Location.UNKNOWN