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(), ]); } }