Add observed 5G WiFi connection time

This commit is contained in:
seo
2026-06-07 18:07:12 +09:00
parent bafdd2d35c
commit 5d366f75a5
3 changed files with 150 additions and 6 deletions
+123
View File
@@ -1458,6 +1458,128 @@ function dedupe_wifi_clients(array $clients): array
return array_values($deduped);
}
function wifi_connected_time_missing(mixed $value): bool
{
$text = strtoupper(trim((string)$value));
return $text === '' || $text === 'N/A' || $text === '-';
}
function observed_wifi_duration_seconds(array $clients): array
{
$targets = [];
foreach ($clients as $client) {
$band = (string)($client['band'] ?? '');
$mac = strtolower((string)($client['mac'] ?? ''));
if ($band !== '5G'
|| !wifi_connected_time_missing($client['connected_time'] ?? null)
|| !preg_match('/^[0-9a-f]{2}(?::[0-9a-f]{2}){5}$/', $mac)
) {
continue;
}
$targets[$mac] = [
'mac' => $mac,
'band' => $band,
'iface' => (string)($client['iface'] ?? ''),
'ip' => (string)($client['ip'] ?? ''),
'hostname' => (string)($client['hostname'] ?? ''),
];
}
if ($targets === []) {
try {
db()->exec("DELETE FROM wifi_observed_sessions WHERE last_seen_at < DATE_SUB(NOW(3), INTERVAL 2 MINUTE)");
} catch (Throwable) {
}
return [];
}
try {
$pdo = db();
$pdo->beginTransaction();
$upsert = $pdo->prepare("
INSERT INTO wifi_observed_sessions
(mac, band, iface, first_seen_at, last_seen_at, last_ip, hostname)
VALUES
(:mac, :band, :iface, NOW(3), NOW(3), :last_ip, :hostname)
ON DUPLICATE KEY UPDATE
band = VALUES(band),
iface = VALUES(iface),
last_seen_at = NOW(3),
last_ip = VALUES(last_ip),
hostname = VALUES(hostname)
");
foreach ($targets as $target) {
$upsert->execute([
':mac' => $target['mac'],
':band' => $target['band'],
':iface' => $target['iface'],
':last_ip' => $target['ip'] === 'N/A' ? null : $target['ip'],
':hostname' => $target['hostname'] === 'N/A' ? null : $target['hostname'],
]);
}
$pdo->exec("DELETE FROM wifi_observed_sessions WHERE last_seen_at < DATE_SUB(NOW(3), INTERVAL 2 MINUTE)");
$placeholders = implode(',', array_fill(0, count($targets), '?'));
$stmt = $pdo->prepare("
SELECT
mac,
GREATEST(0, TIMESTAMPDIFF(SECOND, first_seen_at, NOW(3))) AS observed_seconds
FROM wifi_observed_sessions
WHERE mac IN ($placeholders)
");
$stmt->execute(array_keys($targets));
$rows = $stmt->fetchAll();
$pdo->commit();
$seconds = [];
foreach ($rows as $row) {
$seconds[strtolower((string)$row['mac'])] = (int)$row['observed_seconds'];
}
return $seconds;
} catch (Throwable) {
if (isset($pdo) && $pdo instanceof PDO && $pdo->inTransaction()) {
$pdo->rollBack();
}
return [];
}
}
function apply_observed_wifi_connected_time(array $clients): array
{
$observedSeconds = observed_wifi_duration_seconds($clients);
if ($observedSeconds === []) {
return $clients;
}
foreach ($clients as &$client) {
$mac = strtolower((string)($client['mac'] ?? ''));
if (($client['band'] ?? '') !== '5G'
|| !wifi_connected_time_missing($client['connected_time'] ?? null)
|| !array_key_exists($mac, $observedSeconds)
) {
continue;
}
$client['connected_time'] = (string)$observedSeconds[$mac];
$client['connected_time_source'] = 'observed';
}
unset($client);
return $clients;
}
function wifi_data(): array
{
$leases = dnsmasq_leases();
@@ -1471,6 +1593,7 @@ function wifi_data(): array
}
$clients = dedupe_wifi_clients($clients);
$clients = apply_observed_wifi_connected_time($clients);
return [
'clients' => $clients,