60 lines
1.9 KiB
PHP
60 lines
1.9 KiB
PHP
<?php
|
|
|
|
namespace App\Livewire\Discovery;
|
|
|
|
use App\Models\Device;
|
|
use App\Models\DiscoveryFinding;
|
|
use Livewire\Attributes\Layout;
|
|
use Livewire\Attributes\On;
|
|
use Livewire\Component;
|
|
use PhpMqtt\Client\Facades\MQTT;
|
|
|
|
#[Layout('layouts.app')]
|
|
class Index extends Component
|
|
{
|
|
public bool $rescanning = false;
|
|
|
|
#[On('echo-private:discovery,.DeviceDiscovered')]
|
|
public function onDiscovered(): void {}
|
|
|
|
public function ignore(string $uuid): void
|
|
{
|
|
DiscoveryFinding::where('uuid', $uuid)->update(['status' => 'ignored']);
|
|
}
|
|
|
|
public function unignore(string $uuid): void
|
|
{
|
|
DiscoveryFinding::where('uuid', $uuid)->update(['status' => 'new']);
|
|
}
|
|
|
|
/** Ask the discovery sidecar to re-query the network for participants. */
|
|
public function rescan(): void
|
|
{
|
|
try {
|
|
MQTT::connection()->publish('homeos/sidecar/rescan', (string) now()->getTimestamp(), 0);
|
|
$this->rescanning = true;
|
|
} catch (\Throwable $e) {
|
|
report($e);
|
|
}
|
|
}
|
|
|
|
public function render()
|
|
{
|
|
$findings = DiscoveryFinding::query()->orderByDesc('last_seen_at')->orderByDesc('id')->get();
|
|
|
|
// A finding is only "new" if it hasn't already become a device — either linked at assign
|
|
// (device_id) or auto-onboarded by MQTT (matched by topic prefix). This stops a device
|
|
// showing up both under "Neue Geräte" and under Geräte.
|
|
$knownPrefixes = Device::query()->whereNotNull('config->mqtt_prefix')->get()
|
|
->map(fn ($d) => data_get($d->config, 'mqtt_prefix'))->filter()->values()->all();
|
|
|
|
$isAdded = fn (DiscoveryFinding $f) => $f->device_id !== null
|
|
|| in_array($f->name ?: $f->identifier, $knownPrefixes, true);
|
|
|
|
return view('livewire.discovery.index', [
|
|
'new' => $findings->where('status', 'new')->reject($isAdded)->values(),
|
|
'ignored' => $findings->where('status', 'ignored')->values(),
|
|
]);
|
|
}
|
|
}
|