From 7b039cbefdfdf8af33a4cb33806f88fc9866788b Mon Sep 17 00:00:00 2001 From: Cobra Date: Tue, 14 Apr 2026 14:58:53 -0400 Subject: [PATCH] Use LAA MAC bit to auto-detect phones/wearables for occupancy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Modern phones use private/random MACs (iOS 14+, Android 10+) which always have the locally-administered bit set (bit 1 of first octet). TVs, gateways, and smart home devices use globally-assigned OUI MACs where this bit is clear. No configuration needed — any LAA MAC counts toward occupancy. Explicit device_labels/personal_devices still work as fallback. --- net_alerter/net_alerter.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/net_alerter/net_alerter.py b/net_alerter/net_alerter.py index e9403c6..4766ab1 100644 --- a/net_alerter/net_alerter.py +++ b/net_alerter/net_alerter.py @@ -901,11 +901,18 @@ def _update_occupancy_state_unlocked() -> None: """ global location_occupancy - # Count only explicitly configured personal devices (phones/wearables in device_labels or personal_devices) - # Ignores all other devices — TVs, smart home, unknown equipment, etc. + # Detect phones/wearables via LAA MAC (locally-administered bit set in first octet). + # iOS 14+, Android 10+ all use private/random MACs — this bit is always set. + # TVs, gateways, smart home devices use globally-assigned OUI MACs (bit clear). + # Explicit device_labels / personal_devices also qualify (older phones, pre-config). def _is_personal(mac: str) -> bool: n = _normalize_mac(mac) - return n in device_labels or n in personal_devices + if n in device_labels or n in personal_devices: + return True + try: + return bool(int(n[:2], 16) & 0x02) # locally-administered bit + except ValueError: + return False active_enrolled_count = 0 for mac, dev in known_devices.items():