55 lines
1.5 KiB
PHP
55 lines
1.5 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use UniFi_API\Client;
|
|
|
|
/**
|
|
* Thin wrapper over art-of-wifi/unifi-api-client. Presence source of truth is UniFi
|
|
* (phones associate with the UniFi WLAN, not the Fritz!Box). Uses a read-only local
|
|
* account on the UDM; talks to the LOCAL host with a self-signed cert (verify_ssl off).
|
|
*/
|
|
class UnifiClient
|
|
{
|
|
/** @return array<int, object> active clients (mac, hostname/name, ip, last_seen) */
|
|
public function clients(): array
|
|
{
|
|
$api = $this->connect();
|
|
$clients = $api->list_clients();
|
|
|
|
return is_array($clients) ? $clients : [];
|
|
}
|
|
|
|
/** Lower-cased MACs currently associated. */
|
|
public function connectedMacs(): array
|
|
{
|
|
return array_values(array_filter(array_map(
|
|
fn ($c) => isset($c->mac) ? strtolower($c->mac) : null,
|
|
$this->clients(),
|
|
)));
|
|
}
|
|
|
|
public function isConfigured(): bool
|
|
{
|
|
return filled(config('services.unifi.host')) && filled(config('services.unifi.username'));
|
|
}
|
|
|
|
protected function connect(): Client
|
|
{
|
|
$api = new Client(
|
|
config('services.unifi.username'),
|
|
config('services.unifi.password'),
|
|
'https://'.config('services.unifi.host').':'.config('services.unifi.port'),
|
|
config('services.unifi.site'),
|
|
null,
|
|
config('services.unifi.verify_ssl'),
|
|
);
|
|
|
|
if ($api->login() !== true) {
|
|
throw new \RuntimeException('UniFi login failed — check UNIFI_* credentials.');
|
|
}
|
|
|
|
return $api;
|
|
}
|
|
}
|