- Add password rotation: RotatePasswords console command + migration + service updates - Add PPSK management: UnifiPpsk model, migration, SyncPpskSchedules console - Add VLAN groups and AP groups: VlanGroupController, ApGroupController, model, migration - Add RebootAllAps console command - Add in_alert column to device states - Wire new features through service provider, routes, and existing controllers/services Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
81 lines
3.7 KiB
PHP
81 lines
3.7 KiB
PHP
<?php
|
|
|
|
namespace Dashboard\Unifi\Http\Controllers;
|
|
|
|
use Dashboard\Unifi\Services\UnifiApiClient;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Routing\Controller;
|
|
use Illuminate\Support\Facades\Cache;
|
|
use Inertia\Inertia;
|
|
|
|
class DeviceController extends Controller
|
|
{
|
|
public function index(UnifiApiClient $unifi)
|
|
{
|
|
try {
|
|
$devices = collect($unifi->getDevices())->map(function ($d) {
|
|
// radio_table_stats has actual live channel + per-radio client counts + rates
|
|
$radioStats = collect($d['radio_table_stats'] ?? [])->keyBy('name');
|
|
|
|
// Device-level throughput: prefer device field, fall back to sum of radio stats
|
|
$txRate = ($d['tx_bytes-r'] ?? 0) ?: $radioStats->sum(fn ($r) => $r['tx_bytes-r'] ?? 0);
|
|
$rxRate = ($d['rx_bytes-r'] ?? 0) ?: $radioStats->sum(fn ($r) => $r['rx_bytes-r'] ?? 0);
|
|
|
|
return [
|
|
'mac' => $d['mac'],
|
|
'name' => $d['name'] ?? $d['model'] ?? 'Unknown',
|
|
'model' => $d['model'] ?? '',
|
|
'type' => $d['type'] ?? '',
|
|
'ip' => $d['ip'] ?? '',
|
|
'version' => $d['version'] ?? '',
|
|
'state' => $d['state'] ?? 0,
|
|
'adopted' => $d['adopted'] ?? false,
|
|
'upgradable' => $d['upgradable'] ?? false,
|
|
'uptime' => $d['uptime'] ?? 0,
|
|
'num_sta' => $d['num_sta'] ?? 0,
|
|
'tx_bytes' => $d['tx_bytes'] ?? 0,
|
|
'rx_bytes' => $d['rx_bytes'] ?? 0,
|
|
'tx_rate' => $txRate,
|
|
'rx_rate' => $rxRate,
|
|
'cpu' => $d['system-stats']['cpu'] ?? null,
|
|
'mem' => $d['system-stats']['mem'] ?? null,
|
|
'satisfaction' => $d['satisfaction'] ?? null,
|
|
// Use radio_table_stats for actual channel (not 'auto' from config),
|
|
// per-radio client count, and per-radio rates.
|
|
'channels' => collect($d['radio_table'] ?? [])->map(function ($r) use ($radioStats) {
|
|
$stats = $radioStats->get($r['name'] ?? '');
|
|
// stats['channel'] is the real channel in use; 0 = not broadcasting
|
|
$channel = $stats ? (($stats['channel'] ?? 0) ?: null) : null;
|
|
return [
|
|
'radio' => $r['radio'] ?? '',
|
|
'channel' => $channel,
|
|
'num_sta' => $stats['num_sta'] ?? 0,
|
|
'tx_rate' => $stats ? ($stats['tx_bytes-r'] ?? 0) : 0,
|
|
'rx_rate' => $stats ? ($stats['rx_bytes-r'] ?? 0) : 0,
|
|
];
|
|
})->values(),
|
|
];
|
|
})->values();
|
|
|
|
return Inertia::render('Unifi/Devices', ['devices' => $devices]);
|
|
} catch (\Throwable $e) {
|
|
return Inertia::render('Unifi/Devices', ['devices' => [], 'error' => $e->getMessage()]);
|
|
}
|
|
}
|
|
|
|
public function reboot(Request $request, UnifiApiClient $unifi)
|
|
{
|
|
$request->validate(['mac' => 'required|string|regex:/^([0-9a-f]{2}:){5}[0-9a-f]{2}$/i']);
|
|
|
|
try {
|
|
// Suppress offline/online webhook alerts for planned reboots (15-minute window)
|
|
Cache::put('unifi:planned_reboot:' . strtolower($request->mac), true, now()->addMinutes(15));
|
|
|
|
$unifi->rebootDevice($request->mac);
|
|
return back()->with('success', 'Reboot command sent.');
|
|
} catch (\Throwable $e) {
|
|
return back()->withErrors(['error' => $e->getMessage()]);
|
|
}
|
|
}
|
|
}
|