isConfigured()) { $this->warn('UniFi is not configured (UNIFI_* env).'); return self::SUCCESS; } try { $connected = array_flip($unifi->connectedMacs()); } catch (\Throwable $e) { report($e); $this->error('UniFi poll failed: '.$e->getMessage()); return self::FAILURE; } $this->info('UniFi active clients: '.count($connected)); $debounce = now()->subMinutes(self::AWAY_DEBOUNCE_MINUTES); foreach (Person::whereNotNull('mac')->get() as $person) { $home = isset($connected[strtolower($person->mac)]); if ($home) { $person->last_seen_home_at = now(); if ($person->presence !== 'home') { $this->markPresence($person, 'home'); } else { $person->save(); } continue; } // Not associated: flip to away only once the debounce has elapsed. $seenLongAgo = $person->last_seen_home_at === null || $person->last_seen_home_at->lt($debounce); if ($person->presence !== 'away' && $seenLongAgo) { $this->markPresence($person, 'away'); } } return self::SUCCESS; } private function markPresence(Person $person, string $presence): void { $person->presence = $presence; $person->presence_changed_at = now(); $person->save(); PresenceChanged::dispatch($person->uuid); } }