feat: initial commit — UniFi snap-in package

Full UniFi dashboard snap-in including:
- WiFi/client/device stats with time-series snapshots
- Client Dashboard with traffic, satisfaction, signal, download charts
- Webhook alerting with debounced offline/online detection
- AP snapshot collection, client snapshot collection
- Device classification (type and OS) from OUI/hostname heuristics
- Webhook cooldown, templates, and multi-platform delivery

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Joel Wedemire
2026-04-12 23:00:05 -07:00
commit ce3217d8f4
29 changed files with 2972 additions and 0 deletions

View File

@@ -0,0 +1,56 @@
<?php
namespace Dashboard\Unifi\Http\Controllers;
use Dashboard\Unifi\Services\UnifiApiClient;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Inertia\Inertia;
class DeviceController extends Controller
{
public function index(UnifiApiClient $unifi)
{
try {
$devices = collect($unifi->getDevices())->map(fn ($d) => [
'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,
'cpu' => $d['system-stats']['cpu'] ?? null,
'mem' => $d['system-stats']['mem'] ?? null,
'satisfaction' => $d['satisfaction'] ?? null,
'channels' => collect($d['radio_table'] ?? [])->map(fn ($r) => [
'radio' => $r['radio'] ?? '',
'channel' => $r['channel'] ?? null,
'ht' => $r['ht'] ?? '',
])->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 {
$unifi->rebootDevice($request->mac);
return back()->with('success', 'Reboot command sent.');
} catch (\Throwable $e) {
return back()->withErrors(['error' => $e->getMessage()]);
}
}
}